#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/device.h>
#include <sys/evcount.h>
#include <sys/conf.h>
#include <sys/uio.h>
#include <machine/bus.h>
#include <armv7/omap/omgpiovar.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 "splash16.h"
#define OMDISPLAY_SIZE 0x1000
#define DSS_REVISIONNUMBER 0x00
#define DSS_CONTROL 0x40
#define DSS_PSA_LCD_REG_1 0x50
#define DSS_PSA_LCD_REG_2 0x54
#define DSS_PSA_VIDEO_REG 0x58
#define DSS_STATUS 0x5C
#define DISPC_REVISION 0x0000
#define DISPC_SYSCONFIG 0x0010
#define DISPC_SYSCONFIG_AUTOIDLE 0x00000001
#define DISPC_SYSCONFIG_SOFTRESET 0x00000002
#define DISPC_SYSCONFIG_SIDLEMODE_FORCE 0x00000000
#define DISPC_SYSCONFIG_SIDLEMODE_NONE 0x00000008
#define DISPC_SYSCONFIG_SIDLEMODE_SMART 0x00000010
#define DISPC_SYSCONFIG_MIDLEMODE_FORCE 0x00000000
#define DISPC_SYSCONFIG_MIDLEMODE_NONE 0x00001000
#define DISPC_SYSCONFIG_MIDLEMODE_SMART 0x00002000
#define DISPC_SYSSTATUS 0x0014
#define DISPC_SYSTATUS_RESETDONE 0x00000001
#define DISPC_IRQSTATUS 0x0018
#define DISPC_IRQSTATUS_FRAMEDONE 0x00000001
#define DISPC_IRQSTATUS_VSYNC 0x00000002
#define DISPC_IRQSTATUS_EVSYNCEVEN 0x00000004
#define DISPC_IRQSTATUS_EVSYNCODD 0x00000008
#define DISPC_IRQSTATUS_ACBIASCOUNT 0x00000010
#define DISPC_IRQSTATUS_PROGLINENUM 0x00000020
#define DISPC_IRQSTATUS_GFXFIFOUNDER 0x00000040
#define DISPC_IRQSTATUS_GFXENDWINDOW 0x00000080
#define DISPC_IRQSTATUS_PALGAMMA 0x00000100
#define DISPC_IRQSTATUS_OCPERROR 0x00000200
#define DISPC_IRQSTATUS_VID1FIFOUNDER 0x00000400
#define DISPC_IRQSTATUS_VID1ENDWIND 0x00000800
#define DISPC_IRQSTATUS_VID2FIFOUNDER 0x00001000
#define DISPC_IRQSTATUS_VID2ENDWIND 0x00002000
#define DISPC_IRQSTATUS_SYNCLOST 0x00004000
#define DISPC_IRQENABLE 0x001C
#define DISPC_IRQENABLE_FRAMEDONE 0x00000001
#define DISPC_IRQENABLE_VSYNC 0x00000002
#define DISPC_IRQENABLE_EVSYNCEVEN 0x00000004
#define DISPC_IRQENABLE_EVSYNCODD 0x00000008
#define DISPC_IRQENABLE_ACBIASCOUNT 0x00000010
#define DISPC_IRQENABLE_PROGLINENUM 0x00000020
#define DISPC_IRQENABLE_GFXFIFOUNDER 0x00000040
#define DISPC_IRQENABLE_GFXENDWINDOW 0x00000080
#define DISPC_IRQENABLE_PALGAMMA 0x00000100
#define DISPC_IRQENABLE_OCPERROR 0x00000200
#define DISPC_IRQENABLE_VID1FIFOUNDER 0x00000400
#define DISPC_IRQENABLE_VID1ENDWIND 0x00000800
#define DISPC_IRQENABLE_VID2FIFOUNDER 0x00001000
#define DISPC_IRQENABLE_VID2ENDWIND 0x00002000
#define DISPC_IRQENABLE_SYNCLOST 0x00004000
#define DISPC_CONTROL 0x0040
#define DISPC_CONTROL_LCDENABLE 0x00000001
#define DISPC_CONTROL_DIGITALENABLE 0x00000002
#define DISPC_CONTROL_MONOCOLOR 0x00000004
#define DISPC_CONTROL_STNTFT 0x00000008
#define DISPC_CONTROL_M8B 0x00000010
#define DISPC_CONTROL_GOLCD 0x00000020
#define DISPC_CONTROL_GODIGITAL 0x00000040
#define DISPC_CONTROL_TFTDITHEREN 0x00000080
#define DISPC_CONTROL_TFTDATALINES_12 0x00000000
#define DISPC_CONTROL_TFTDATALINES_16 0x00000100
#define DISPC_CONTROL_TFTDATALINES_18 0x00000200
#define DISPC_CONTROL_TFTDATALINES_24 0x00000300
#define DISPC_CONTROL_SECURE 0x00000400
#define DISPC_CONTROL_RFBIMODE 0x00000800
#define DISPC_CONTROL_OVERLAYOPT 0x00001000
#define DISPC_CONTROL_GPIN0 0x00002000
#define DISPC_CONTROL_GPIN1 0x00004000
#define DISPC_CONTROL_GPOUT0 0x00008000
#define DISPC_CONTROL_GPOUT1 0x00010000
#define DISPC_CONTROL_HT 0x00070000
#define DISPC_CONTROL_HT_s(x) ((x) << 17)
#define DISPC_CONTROL_TDMENABLE 0x00100000
#define DISPC_CONTROL_TDMPARALLEL_8 0x00000000
#define DISPC_CONTROL_TDMPARALLEL_9 0x00200000
#define DISPC_CONTROL_TDMPARALLEL_12 0x00400000
#define DISPC_CONTROL_TDMPARALLEL_16 0x00600000
#define DISPC_CONTROL_TDMCYCLE_1 0x00000000
#define DISPC_CONTROL_TDMCYCLE_2 0x00800000
#define DISPC_CONTROL_TDMCYCLE_3 0x00000000
#define DISPC_CONTROL_TDMCYCLE_3_2 0x01800000
#define DISPC_CONTROL_TDMUNUSED_0 0x00000000
#define DISPC_CONTROL_TDMUNUSED_1 0x02000000
#define DISPC_CONTROL_TDMUNUSED_M 0x04000000
#define DISPC_CONFIG 0x0044
#define DISPC_CONFIG_PIXELGATED 0x00000001
#define DISPC_CONFIG_LOADMODE_PGE 0x00000000
#define DISPC_CONFIG_LOADMODE_PG 0x00000002
#define DISPC_CONFIG_LOADMODE_DATA 0x00000004
#define DISPC_CONFIG_LOADMODE_DATA_PG 0x00000006
#define DISPC_CONFIG_PALETTEGAMMA 0x00000008
#define DISPC_CONFIG_PIXELDATAGATED 0x00000010
#define DISPC_CONFIG_PIXELCLOCKGATED 0x00000020
#define DISPC_CONFIG_HSYNCGATED 0x00000040
#define DISPC_CONFIG_VSYNCGATED 0x00000080
#define DISPC_CONFIG_ACBIAGATED 0x00000100
#define DISPC_CONFIG_FUNCGATED 0x00000200
#define DISPC_CONFIG_TCKLCDEN 0x00000400
#define DISPC_CONFIG_TCKLCDSEL 0x00000800
#define DISPC_CONFIG_TCKDIGEN 0x00001000
#define DISPC_CONFIG_TCKDIGSEL 0x00002000
#define DISPC_CAPABLE 0x0048
#define DISPC_DEFAULT_COLOR0 0x004C
#define DISPC_DEFAULT_COLOR1 0x0050
#define DISPC_TRANS_COLOR0 0x0054
#define DISPC_TRANS_COLOR1 0x0058
#define DISPC_LINE_STATUS 0x005C
#define DISPC_LINE_NUMBER 0x0060
#define DISPC_TIMING_H 0x0064
#define DISPC_TIMING_H_HSW_s(x) ((x) << 0)
#define DISPC_TIMING_H_HFP_s(x) ((x) << 8)
#define DISPC_TIMING_H_HBP_s(x) ((x) << 20)
#define DISPC_TIMING_V 0x0068
#define DISPC_TIMING_V_VSW_s(x) ((x) << 0)
#define DISPC_TIMING_V_VFP_s(x) ((x) << 8)
#define DISPC_TIMING_V_VBP_s(x) ((x) << 20)
#define DISPC_POL_FREQ 0x006C
#define DISPC_POL_FREQ_ACB_s(x) ((x) << 0)
#define DISPC_POL_FREQ_ACBI_s(x) ((x) << 8)
#define DISPC_POL_FREQ_IVS 0x00001000
#define DISPC_POL_FREQ_IHS 0x00002000
#define DISPC_POL_FREQ_IPC 0x00004000
#define DISPC_POL_FREQ_IEO 0x00008000
#define DISPC_POL_FREQ_RF 0x00010000
#define DISPC_POL_FREQ_ONOFF 0x00020000
#define DISPC_DIVISOR 0x0070
#define DISPC_DIVISOR_PCD_s(x) ((x) << 0)
#define DISPC_DIVISOR_LCD_s(x) ((x) << 16)
#define DISPC_SIZE_DIG 0x0078
#define DISPC_SIZE_DIG_PPL_s(x) ((x) << 0)
#define DISPC_SIZE_DIG_LPP_s(x) ((x) << 16)
#define DISPC_SIZE_LCD 0x007C
#define DISPC_SIZE_LCD_PPL_s(x) ((x) << 0)
#define DISPC_SIZE_LCD_LPP_s(x) ((x) << 16)
#define DISPC_GFX_BA0 0x0080
#define DISPC_GFX_BA1 0x0084
#define DISPC_GFX_POSITION 0x0088
#define DISPC_GFX_SIZE 0x008C
#define DISPC_GFX_SIZE_X_s(x) ((x) << 0)
#define DISPC_GFX_SIZE_Y_s(x) ((x) << 16)
#define DISPC_GFX_ATTRIBUTES 0x00A0
#define DISPC_GFX_ATTRIBUTES_GFXENABLE 0x001
#define DISPC_GFX_ATTRIBUTES_GFXFMT_1 0x000
#define DISPC_GFX_ATTRIBUTES_GFXFMT_2 0x002
#define DISPC_GFX_ATTRIBUTES_GFXFMT_4 0x004
#define DISPC_GFX_ATTRIBUTES_GFXFMT_8 0x006
#define DISPC_GFX_ATTRIBUTES_GFXFMT_12 0x008
#define DISPC_GFX_ATTRIBUTES_GFXFMT_16 0x00c
#define DISPC_GFX_ATTRIBUTES_GFXFMT_24 0x010
#define DISPC_GFX_ATTRIBUTES_GFXREPLICATE 0x020
#define DISPC_GFX_ATTRIBUTES_BURST_4 0x000
#define DISPC_GFX_ATTRIBUTES_BURST_8 0x040
#define DISPC_GFX_ATTRIBUTES_BURST_16 0x080
#define DISPC_GFX_ATTRIBUTES_GFXCHANNELOUT 0x100
#define DISPC_GFX_ATTRIBUTES_NIBBLEMODE 0x200
#define DISPC_GFX_ATTRIBUTES_ENDIAN 0x400
#define DISPC_GFX_FIFO_THRESHOLD 0x00A4
#define DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT 16
#define DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT 0
#define DISPC_GFX_FIFO_SIZE_STATUS 0x00A8
#define DISPC_GFX_ROW_INC 0x00AC
#define DISPC_GFX_PIXEL_INC 0x00B0
#define DISPC_GFX_WINDOW_SKIP 0x00B4
#define DISPC_GFX_TABLE_BA 0x00B8
#define DISPC_VID1_BA0 0x00BC
#define DISPC_VID1_BA1 0x00C0
#define DISPC_VID1_POSITION 0x00C4
#define DISPC_VID1_SIZE 0x00C8
#define DISPC_VID1_ATTRIBUTES 0x00CC
#define DISPC_VID1_FIFO_THRESHOLD 0x00D0
#define DISPC_VID1_FIFO_SIZE_STATUS 0x00D4
#define DISPC_VID1_ROW_INC 0x00D8
#define DISPC_VID1_PIXEL_INC 0x00DC
#define DISPC_VID1_FIR 0x00E0
#define DISPC_VID1_PICTURE_SIZE 0x00E4
#define DISPC_VID1_ACCU0 0x00E8
#define DISPC_VID1_ACCU1 0x00EC
#define DISPC_VID1_FIR_COEF_H0 0x00F0
#define DISPC_VID1_FIR_COEF_H1 0x00F8
#define DISPC_VID1_FIR_COEF_H2 0x0100
#define DISPC_VID1_FIR_COEF_H3 0x0108
#define DISPC_VID1_FIR_COEF_H4 0x0110
#define DISPC_VID1_FIR_COEF_H5 0x0118
#define DISPC_VID1_FIR_COEF_H6 0x0120
#define DISPC_VID1_FIR_COEF_H7 0x0128
#define DISPC_VID1_FIR_COEF_HV0 0x00F4
#define DISPC_VID1_FIR_COEF_HV1 0x00FC
#define DISPC_VID1_FIR_COEF_HV2 0x0104
#define DISPC_VID1_FIR_COEF_HV3 0x010C
#define DISPC_VID1_FIR_COEF_HV4 0x0114
#define DISPC_VID1_FIR_COEF_HV5 0x011C
#define DISPC_VID1_FIR_COEF_HV6 0x0124
#define DISPC_VID1_FIR_COEF_HV7 0x012C
#define DISPC_VID1_CONV_COEF0 0x0130
#define DISPC_VID1_CONV_COEF1 0x0134
#define DISPC_VID1_CONV_COEF2 0x0138
#define DISPC_VID1_CONV_COEF3 0x013C
#define DISPC_VID1_CONV_COEF4 0x0140
#define DISPC_VID2_BA0 0x014C
#define DISPC_VID2_BA1 0x0150
#define DISPC_VID2_POSITION 0x0154
#define DISPC_VID2_SIZE 0x0158
#define DISPC_VID2_ATTRIBUTES 0x015C
#define DISPC_VID2_FIFO_THRESHOLD 0x0160
#define DISPC_VID2_FIFO_SIZE_STATUS 0x0164
#define DISPC_VID2_ROW_INC 0x0168
#define DISPC_VID2_PIXEL_INC 0x016C
#define DISPC_VID2_FIR 0x0170
#define DISPC_VID2_PICTURE_SIZE 0x0174
#define DISPC_VID2_ACCU0 0x0178
#define DISPC_VID2_ACCU1 0x017C
#define DISPC_VID2_FIR_COEF_H0 0x0180
#define DISPC_VID2_FIR_COEF_H1 0x0188
#define DISPC_VID2_FIR_COEF_H2 0x0190
#define DISPC_VID2_FIR_COEF_H3 0x0198
#define DISPC_VID2_FIR_COEF_H4 0x01A0
#define DISPC_VID2_FIR_COEF_H5 0x01A8
#define DISPC_VID2_FIR_COEF_H6 0x01B0
#define DISPC_VID2_FIR_COEF_H7 0x01B8
#define DISPC_VID2_FIR_COEF_HV0 0x0184
#define DISPC_VID2_FIR_COEF_HV1 0x018C
#define DISPC_VID2_FIR_COEF_HV2 0x0194
#define DISPC_VID2_FIR_COEF_HV3 0x019C
#define DISPC_VID2_FIR_COEF_HV4 0x01A4
#define DISPC_VID2_FIR_COEF_HV5 0x01AC
#define DISPC_VID2_FIR_COEF_HV6 0x01B4
#define DISPC_VID2_FIR_COEF_HV7 0x01BC
#define DISPC_VID2_CONV_COEF0 0x01C0
#define DISPC_VID2_CONV_COEF1 0x01C4
#define DISPC_VID2_CONV_COEF2 0x01C8
#define DISPC_VID2_CONV_COEF3 0x01CC
#define DISPC_VID2_CONV_COEF4 0x01D0
#define DISPC_DATA_CYCLE1 0x01D4
#define DISPC_DATA_CYCLE2 0x01D8
#define DISPC_DATA_CYCLE3 0x01DC
#define DISPC_SIZE 0x0200
#define RFBI_REVISION 0x0000
#define RFBI_SYSCONFIG 0x0010
#define RFBI_SYSSTATUS 0x0014
#define RFBI_CONTROL 0x0040
#define RFBI_PIXEL_CNT 0x0044
#define RFBI_LINE_NUMBER 0x0048
#define RFBI_CMD 0x004C
#define RFBI_PARAM 0x0050
#define RFBI_DATA 0x0054
#define RFBI_READ 0x0058
#define RFBI_STATUS 0x005C
#define RFBI_CONFIG0 0x0060
#define RFBI_CONFIG1 0x0078
#define RFBI_ONOFF_TIME0 0x0064
#define RFBI_ONOFF_TIME1 0x007C
#define RFBI_CYCLE_TIME0 0x0068
#define RFBI_CYCLE_TIME1 0x0080
#define RFBI_DATA_CYCLE1_0 0x006C
#define RFBI_DATA_CYCLE1_1 0x0084
#define RFBI_DATA_CYCLE2_0 0x0070
#define RFBI_DATA_CYCLE2_1 0x0088
#define RFBI_DATA_CYCLE3_0 0x0074
#define RFBI_DATA_CYCLE3_1 0x008C
#define RFBI_VSYNC_WIDTH 0x0090
#define RFBI_HSYNC_WIDTH 0x0094
#define REV_ID 0x0000
#define STATUS 0x0004
#define F_CONTROL 0x0008
#define VIDOUT_CTRL 0x0010
#define SYNC_CTRL 0x0014
#define LLEN 0x001C
#define FLENS 0x0020
#define HFLTR_CTRL 0x0024
#define CC_CARR_WSS_CARR 0x0028
#define C_PHASE 0x002C
#define GAIN_U 0x0030
#define GAIN_V 0x0034
#define GAIN_Y 0x0038
#define BLACK_LEVEL 0x003C
#define BLANK_LEVEL 0x0040
#define X_COLOR 0x0044
#define M_CONTROL 0x0048
#define BSTAMP_WSS_DATA 0x004C
#define S_CARR 0x0050
#define LINE21 0x0054
#define LN_SEL 0x0058
#define L21_WC_CTL 0x005C
#define HTRIGGER_VTRIGGER 0x0060
#define SAVID_EAVID 0x0064
#define FLEN_FAL 0x0068
#define LAL_PHASE_RESET 0x006C
#define HS_INT_START_STOP_X 0x0070
#define HS_EXT_START_STOP_X 0x0074
#define VS_INT_START_X 0x0078
#define VS_INT_STOP_X_VS_INT_START_Y 0x007C
#define VS_INT_STOP_Y_VS_EXT_START_X 0x0080
#define VS_EXT_STOP_X_VS_EXT_START_Y 0x0084
#define VS_EXT_STOP_Y 0x0088
#define AVID_START_STOP_X 0x0090
#define AVID_START_STOP_Y 0x0094
#define FID_INT_START_X_FID_INT_START_Y 0x00A0
#define FID_INT_OFFSET_Y_FID_EXT_START_X 0x00A4
#define FID_EXT_START_Y_FID_EXT_OFFSET_Y 0x00A8
#define TVDETGP_INT_START_STOP_X 0x00B0
#define TVDETGP_INT_START_STOP_Y 0x00B4
#define GEN_CTRL 0x00B8
#define DAC_TST_DAC_A 0x00C4
#define DAC_B_DAC_C 0x00C8
struct omdisplay_panel_data {
int width;
int height;
int horiz_sync_width;
int horiz_front_porch;
int horiz_back_porch;
int vert_sync_width;
int vert_front_porch;
int vert_back_porch;
int panel_flags;
int sync;
int depth;
#define PANEL_SYNC_H_ACTIVE_HIGH 1
#define PANEL_SYNC_V_ACTIVE_HIGH 2
int linebytes;
};
#define PIXELDEPTH 16
#define PIXELWIDTH 2
struct omdisplay_panel_data default_panel = {
240,
322,
9, 9, 19,
1, 2, 2,
0,
0,
PIXELDEPTH,
240*PIXELWIDTH
};
struct omdisplay_screen {
LIST_ENTRY(omdisplay_screen) link;
bus_dmamap_t dma;
bus_dma_segment_t segs[1];
int nsegs;
size_t buf_size;
size_t map_size;
void *buf_va;
int depth;
struct rasops_info rinfo;
};
struct omdisplay_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_dsioh;
bus_space_handle_t sc_dcioh;
bus_space_handle_t sc_rfbioh;
bus_space_handle_t sc_venioh;
bus_dma_tag_t sc_dma_tag;
void *sc_ih;
int sc_nscreens;
LIST_HEAD(,omdisplay_screen) sc_screens;
struct omdisplay_panel_data *sc_geometry;
struct omdisplay_screen *sc_active;
};
int omdisplay_match(struct device *parent, void *v, void *aux);
void omdisplay_attach(struct device *parent, struct device *self, void *args);
int omdisplay_activate(struct device *, int);
int omdisplay_ioctl(void *v, u_long cmd, caddr_t data, int flag,
struct proc *p);
void omdisplay_burner(void *v, u_int on, u_int flags);
int omdisplay_show_screen(void *v, void *cookie, int waitok,
void (*cb)(void *, int, int), void *cbarg);
int omdisplay_param(struct omdisplay_softc *sc, ulong cmd,
struct wsdisplay_param *dp);
int omdisplay_max_brightness(void);
int omdisplay_get_brightness(void);
void omdisplay_set_brightness(int newval);
void omdisplay_set_brightness_internal(int newval);
int omdisplay_get_backlight(void);
void omdisplay_set_backlight(int on);
void omdisplay_blank(int blank);
void omdisplay_suspend(struct omdisplay_softc *sc);
void omdisplay_resume(struct omdisplay_softc *sc);
void omdisplay_initialize(struct omdisplay_softc *sc,
struct omdisplay_panel_data *geom);
void omdisplay_setup_rasops(struct omdisplay_softc *sc,
struct rasops_info *rinfo);
int omdisplay_alloc_screen(void *v, const struct wsscreen_descr *_type,
void **cookiep, int *curxp, int *curyp, uint32_t *attrp);
int omdisplay_new_screen(struct omdisplay_softc *sc,
struct omdisplay_screen *scr, int depth);
paddr_t omdisplay_mmap(void *v, off_t offset, int prot);
int omdisplay_load_font(void *, void *, struct wsdisplay_font *);
int omdisplay_list_font(void *, struct wsdisplay_font *);
void omdisplay_free_screen(void *v, void *cookie);
void omdisplay_start(struct omdisplay_softc *sc);
void omdisplay_stop(struct omdisplay_softc *sc);
int omdisplay_intr(void *v);
const struct cfattach omdisplay_ca = {
sizeof (struct omdisplay_softc), omdisplay_match, omdisplay_attach,
NULL, omdisplay_activate
};
struct cfdriver omdisplay_cd = {
NULL, "omdisplay", DV_DULL
};
struct wsdisplay_accessops omdisplay_accessops = {
.ioctl = omdisplay_ioctl,
.mmap = omdisplay_mmap,
.alloc_screen = omdisplay_alloc_screen,
.free_screen = omdisplay_free_screen,
.show_screen = omdisplay_show_screen,
.load_font = omdisplay_load_font,
.list_font = omdisplay_list_font,
.burn_screen = omdisplay_burner
};
struct omdisplay_wsscreen_descr {
struct wsscreen_descr c;
int depth;
int flags;
};
struct omdisplay_wsscreen_descr omdisplay_screen = {
{
"std"
},
16,
0
};
const struct wsscreen_descr *omdisplay_scr_descr[] = {
&omdisplay_screen.c
};
const struct wsscreen_list omdisplay_screen_list = {
sizeof omdisplay_scr_descr / sizeof omdisplay_scr_descr[0],
omdisplay_scr_descr
};
int
omdisplay_match(struct device *parent, void *v, void *aux)
{
return (1);
}
void
omdisplay_attach(struct device *parent, struct device *self, void *args)
{
struct ahb_attach_args *aa = args;
struct omdisplay_softc *sc = (struct omdisplay_softc *) self;
struct wsemuldisplaydev_attach_args wsaa;
sc->sc_iot = aa->aa_iot;
if (bus_space_map(sc->sc_iot, aa->aa_addr, OMDISPLAY_SIZE, 0,
&sc->sc_dsioh))
panic("omdisplay_attach: bus_space_map failed!");
if (bus_space_subregion(sc->sc_iot, sc->sc_dsioh, 0x400, 1024,
&sc->sc_dcioh))
panic("omdisplay_attach: bus_space_submap failed!");
if (bus_space_subregion(sc->sc_iot, sc->sc_dsioh, 0x800, 1024,
&sc->sc_rfbioh))
panic("omdisplay_attach: bus_space_submap failed!");
if (bus_space_subregion(sc->sc_iot, sc->sc_dsioh, 0xc00, 1024,
&sc->sc_venioh))
panic("omdisplay_attach: bus_space_submap failed!");
sc->sc_nscreens = 0;
LIST_INIT(&sc->sc_screens);
sc->sc_dma_tag = aa->aa_dmat;
sc->sc_ih = arm_intr_establish(aa->aa_intr, IPL_BIO ,
omdisplay_intr, sc, sc->sc_dev.dv_xname);
printf ("\n");
sc->sc_geometry = &default_panel;
{
struct rasops_info dummy;
omdisplay_initialize(sc, sc->sc_geometry);
bzero(&dummy, sizeof(dummy));
omdisplay_setup_rasops(sc, &dummy);
}
wsaa.console = 0;
wsaa.scrdata = &omdisplay_screen_list;
wsaa.accessops = &omdisplay_accessops;
wsaa.accesscookie = sc;
wsaa.defaultscreens = 0;
(void)config_found(self, &wsaa, wsemuldisplaydevprint);
}
int
omdisplay_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
{
struct omdisplay_softc *sc = v;
struct wsdisplay_fbinfo *wsdisp_info;
struct omdisplay_screen *scr = sc->sc_active;
int res = EINVAL;
switch (cmd) {
case WSDISPLAYIO_GETPARAM:
case WSDISPLAYIO_SETPARAM:
res = omdisplay_param(sc, cmd, (struct wsdisplay_param *)data);
break;
case WSDISPLAYIO_GTYPE:
*(u_int *)data = WSDISPLAY_TYPE_PXALCD;
break;
case WSDISPLAYIO_GINFO:
wsdisp_info = (struct wsdisplay_fbinfo *)data;
wsdisp_info->height = sc->sc_geometry->height;
wsdisp_info->width = sc->sc_geometry->width;
wsdisp_info->depth = 16;
if (scr != NULL)
wsdisp_info->stride = scr->rinfo.r_stride;
else
wsdisp_info->stride = 0;
wsdisp_info->offset = 0;
wsdisp_info->cmsize = 0;
break;
case WSDISPLAYIO_GETCMAP:
case WSDISPLAYIO_PUTCMAP:
return EINVAL;
case WSDISPLAYIO_SVIDEO:
case WSDISPLAYIO_GVIDEO:
break;
case WSDISPLAYIO_GCURPOS:
case WSDISPLAYIO_SCURPOS:
case WSDISPLAYIO_GCURMAX:
case WSDISPLAYIO_GCURSOR:
case WSDISPLAYIO_SCURSOR:
default:
return -1;
case WSDISPLAYIO_LINEBYTES:
if (scr != NULL)
*(u_int *)data = scr->rinfo.ri_stride;
else
*(u_int *)data = 0;
break;
}
if (res == EINVAL)
res = omdisplay_ioctl(v, cmd, data, flag, p);
return res;
}
void
omdisplay_burner(void *v, u_int on, u_int flags)
{
omdisplay_set_brightness(on ? omdisplay_get_brightness() : 0);
if (on) {
omgpio_set_bit(93);
omgpio_set_dir(93, OMGPIO_DIR_OUT);
omgpio_clear_bit(26);
omgpio_set_dir(26, OMGPIO_DIR_OUT);
} else {
omgpio_clear_bit(93);
omgpio_set_dir(93, OMGPIO_DIR_OUT);
omgpio_set_bit(26);
omgpio_set_dir(26, OMGPIO_DIR_OUT);
}
}
int
omdisplay_show_screen(void *v, void *cookie, int waitok,
void (*cb)(void *, int, int), void *cbarg)
{
struct omdisplay_softc *sc = v;
struct rasops_info *ri = cookie;
struct omdisplay_screen *scr = ri->ri_hw, *old;
old = sc->sc_active;
if (old == scr)
return 0;
if (old != NULL)
;
sc->sc_active = scr;
omdisplay_initialize(sc, sc->sc_geometry);
omdisplay_burner(v, 1, 0);
return (0);
}
int
omdisplay_param(struct omdisplay_softc *sc, ulong cmd,
struct wsdisplay_param *dp)
{
int res = EINVAL;
switch (dp->param) {
case WSDISPLAYIO_PARAM_BACKLIGHT:
if (cmd == WSDISPLAYIO_GETPARAM) {
dp->min = 0;
dp->max = 1;
dp->curval = omdisplay_get_backlight();
res = 0;
} else if (cmd == WSDISPLAYIO_SETPARAM) {
res = 0;
}
break;
case WSDISPLAYIO_PARAM_CONTRAST:
res = ENOTTY;
break;
case WSDISPLAYIO_PARAM_BRIGHTNESS:
if (cmd == WSDISPLAYIO_GETPARAM) {
dp->min = 1;
dp->max = omdisplay_max_brightness();
dp->curval = omdisplay_get_brightness();
res = 0;
} else if (cmd == WSDISPLAYIO_SETPARAM) {
res = 0;
}
break;
}
return res;
}
static int lcdbrightnesscurval = 1;
static int lcdislit = 1;
static int lcdisblank = 0;
struct lcd_backlight {
int duty;
int cont;
int on;
};
const struct lcd_backlight lcd_bl[] = {
{ 0x00, 0, 0 },
{ 0x00, 0, 1 },
{ 0x01, 0, 1 },
{ 0x07, 0, 1 },
{ 0x01, 1, 1 },
{ 0x07, 1, 1 },
{ 0x11, 1, 1 },
{ -1, -1, -1 }
};
#define CURRENT_BACKLIGHT lcd_bl
int
omdisplay_max_brightness(void)
{
int i;
for (i = 0; CURRENT_BACKLIGHT[i].duty != -1; i++)
;
return i - 1;
}
int
omdisplay_get_brightness(void)
{
return lcdbrightnesscurval;
}
void
omdisplay_set_brightness(int newval)
{
int max;
max = omdisplay_max_brightness();
if (newval < 0)
newval = 0;
else if (newval > max)
newval = max;
if (omdisplay_get_backlight() && !lcdisblank)
omdisplay_set_brightness_internal(newval);
if (newval > 0)
lcdbrightnesscurval = newval;
}
void
omdisplay_set_brightness_internal(int newval)
{
static int curval = 1;
int i;
if (newval > curval) {
for (i = curval + 1; i <= newval; i++) {
}
} else {
}
curval = newval;
}
int
omdisplay_get_backlight(void)
{
return lcdislit;
}
void
omdisplay_set_backlight(int on)
{
if (!on) {
omdisplay_set_brightness(0);
lcdislit = 0;
} else {
lcdislit = 1;
omdisplay_set_brightness(omdisplay_get_brightness());
}
}
void
omdisplay_blank(int blank)
{
if (blank) {
omdisplay_set_brightness(0);
lcdisblank = 1;
} else {
lcdisblank = 0;
omdisplay_set_brightness(omdisplay_get_brightness());
}
}
void
omdisplay_suspend(struct omdisplay_softc *sc)
{
if (sc->sc_active != NULL) {
omdisplay_stop(sc);
}
}
void
omdisplay_resume(struct omdisplay_softc *sc)
{
if (sc->sc_active != NULL) {
omdisplay_initialize(sc, sc->sc_geometry);
omdisplay_start(sc);
}
}
void
omdisplay_activate(struct device *self, int act)
{
struct omdisplay_softc *sc = (struct omdisplay_softc *)self;
switch (act) {
case DVACT_SUSPEND:
omdisplay_set_brightness(0);
omdisplay_suspend(sc);
break;
case DVACT_RESUME:
omdisplay_resume(sc);
omdisplay_set_brightness(omdisplay_get_brightness());
break;
}
return 0;
}
void
omdisplay_initialize(struct omdisplay_softc *sc,
struct omdisplay_panel_data *geom)
{
struct omdisplay_screen *scr;
u_int32_t reg;
u_int32_t mode;
#if 0
int den, nom;
#endif
reg = bus_space_read_4(sc->sc_iot, sc->sc_dcioh, DISPC_CONTROL);
scr = sc->sc_active;
if (reg & (DISPC_CONTROL_LCDENABLE|DISPC_CONTROL_DIGITALENABLE)) {
omdisplay_stop(sc);
}
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_IRQENABLE, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_CONFIG,
DISPC_CONFIG_LOADMODE_PG|DISPC_CONFIG_LOADMODE_DATA);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DEFAULT_COLOR0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DEFAULT_COLOR1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_TRANS_COLOR0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_TRANS_COLOR1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_LINE_NUMBER, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DATA_CYCLE1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DATA_CYCLE2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DATA_CYCLE3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_SYSCONFIG,
DISPC_SYSCONFIG_SIDLEMODE_NONE|
DISPC_SYSCONFIG_MIDLEMODE_NONE);
#if 0
if (geom->panel_flags & LCDPANEL_TDM) {
nom = tdmflags >>8 & 0x3;
den = tdmflags & 0x3;
} else {
nom = 1;
den = 1;
}
hsync = geom->width*den/nom + geom->horiz_sync_width +
geom->horiz_front_porch + geom->horiz_back_porch;
#endif
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_TIMING_H,
DISPC_TIMING_H_HSW_s(geom->horiz_sync_width) |
DISPC_TIMING_H_HFP_s(geom->horiz_front_porch) |
DISPC_TIMING_H_HBP_s(geom->horiz_back_porch));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_TIMING_V,
DISPC_TIMING_V_VSW_s(geom->vert_sync_width) |
DISPC_TIMING_V_VFP_s(geom->vert_front_porch) |
DISPC_TIMING_V_VBP_s(geom->vert_back_porch));
reg = 0;
if (geom->sync & PANEL_SYNC_H_ACTIVE_HIGH)
reg |= DISPC_POL_FREQ_IHS;
if (geom->sync & PANEL_SYNC_V_ACTIVE_HIGH)
reg |= DISPC_POL_FREQ_IVS;
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_POL_FREQ, reg);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_SIZE_LCD,
DISPC_SIZE_LCD_PPL_s(geom->width-1) |
DISPC_SIZE_LCD_LPP_s(geom->height-1));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_SIZE_DIG,
DISPC_SIZE_LCD_PPL_s(geom->width-1) |
DISPC_SIZE_LCD_LPP_s(geom->height-1));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_SIZE,
DISPC_GFX_SIZE_X_s(geom->width-1) |
DISPC_GFX_SIZE_Y_s(geom->height-1));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_DIVISOR,
DISPC_DIVISOR_LCD_s(1) | DISPC_DIVISOR_PCD_s(6));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_BA0,
scr->segs[0].ds_addr);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_BA1,
scr->segs[0].ds_addr);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_PIXEL_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_ROW_INC,
1 + scr->rinfo.ri_stride -
(scr->rinfo.ri_width * scr->rinfo.ri_depth / 8));
switch (geom->depth) {
case 1:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_1;
break;
case 2:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_2;
break;
case 4:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_4;
break;
case 8:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_8;
break;
case 12:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_12;
break;
case 16:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_16;
break;
case 24:
mode = DISPC_GFX_ATTRIBUTES_GFXFMT_24;
break;
default:
panic("invalid depth %d", geom->depth);
}
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_ATTRIBUTES,
DISPC_GFX_ATTRIBUTES_GFXENABLE | mode |
DISPC_GFX_ATTRIBUTES_BURST_8);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_POSITION, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_WINDOW_SKIP, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_FIFO_THRESHOLD,
(0xfc << DISPC_GFX_FIFO_THRESHOLD_HIGH_SHIFT) |
(0xc0 << DISPC_GFX_FIFO_THRESHOLD_LOW_SHIFT));
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_ROW_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_PIXEL_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_GFX_TABLE_BA,
scr->segs[0].ds_addr);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_BA0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_BA1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_SIZE, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_ATTRIBUTES, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIFO_THRESHOLD,
0xc00040);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIFO_SIZE_STATUS,
0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_ROW_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_PIXEL_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_PICTURE_SIZE, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_ACCU0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_ACCU1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H4, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H5, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H6, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_H7, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV4, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV5, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV6, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_FIR_COEF_HV7, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_CONV_COEF0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_CONV_COEF1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_CONV_COEF2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_CONV_COEF3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID1_CONV_COEF4, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_BA0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_BA1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_SIZE, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_ATTRIBUTES, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIFO_THRESHOLD,
0xc00040);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIFO_SIZE_STATUS,
0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_ROW_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_PIXEL_INC, 1);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_PICTURE_SIZE, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_ACCU0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_ACCU1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H4, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H5, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H6, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_H7, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV4, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV5, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV6, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_FIR_COEF_HV7, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_CONV_COEF0, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_CONV_COEF1, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_CONV_COEF2, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_CONV_COEF3, 0);
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_VID2_CONV_COEF4, 0);
omdisplay_start(sc);
}
void
omdisplay_setup_rasops(struct omdisplay_softc *sc, struct rasops_info *rinfo)
{
struct omdisplay_wsscreen_descr *descr;
struct omdisplay_panel_data *geom;
descr = &omdisplay_screen;
geom = sc->sc_geometry;
rinfo->ri_flg = descr->flags;
rinfo->ri_depth = descr->depth;
rinfo->ri_width = geom->width;
rinfo->ri_height = geom->height;
rinfo->ri_stride = geom->linebytes;
if (descr->depth == 16) {
rinfo->ri_rnum = 5;
rinfo->ri_rpos = 11;
rinfo->ri_gnum = 6;
rinfo->ri_gpos = 5;
rinfo->ri_bnum = 5;
rinfo->ri_bpos = 0;
}
if (descr->c.nrows == 0) {
rasops_init(rinfo, 100, 100);
} else {
if (descr->flags != 0)
rasops_init(rinfo, descr->c.ncols, descr->c.nrows);
else
rasops_init(rinfo, descr->c.nrows, descr->c.ncols);
}
descr->c.nrows = rinfo->ri_rows;
descr->c.ncols = rinfo->ri_cols;
descr->c.capabilities = rinfo->ri_caps;
descr->c.textops = &rinfo->ri_ops;
}
int
omdisplay_alloc_screen(void *v, const struct wsscreen_descr *_type,
void **cookiep, int *curxp, int *curyp, uint32_t *attrp)
{
struct omdisplay_softc *sc = v;
struct omdisplay_screen *scr;
struct rasops_info *ri;
struct omdisplay_wsscreen_descr *type =
(struct omdisplay_wsscreen_descr *)_type;
int error;
scr = malloc(sizeof *scr, M_DEVBUF, (cold ? M_NOWAIT : M_WAITOK));
if (scr == NULL)
return (ENOMEM);
error = omdisplay_new_screen(sc, scr, type->depth);
if (error != 0) {
free(scr, M_DEVBUF, 0);
return (error);
}
ri = &scr->rinfo;
ri->ri_hw = (void *)scr;
ri->ri_bits = scr->buf_va;
omdisplay_setup_rasops(sc, ri);
ri->ri_ops.pack_attr(ri, 0, 0, 0, attrp);
*cookiep = ri;
*curxp = 0;
*curyp = 0;
return 0;
}
int
omdisplay_new_screen(struct omdisplay_softc *sc,
struct omdisplay_screen *scr, int depth)
{
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_dma_tag_t dma_tag;
struct omdisplay_panel_data *geometry;
int width, height;
bus_size_t size;
int error, palette_size;
int busdma_flag = (cold ? BUS_DMA_NOWAIT : BUS_DMA_WAITOK);
if (sc != NULL) {
iot = sc->sc_iot;
ioh = sc->sc_dcioh;
dma_tag = sc->sc_dma_tag;
geometry = sc->sc_geometry;
} else {
#if 0
iot = omdisplay_console.iot;
ioh = omdisplay_console.ioh;
dma_tag = omdisplay_console.dma_tag;
geometry = omdisplay_console.geometry;
#endif
}
width = geometry->width;
height = geometry->height;
palette_size = 0;
switch (depth) {
case 1:
case 2:
case 4:
case 8:
palette_size = (1 << depth) * sizeof (uint16_t);
case 16:
case 24:
size = geometry->height * geometry->linebytes;
break;
default:
printf("%s: Unknown depth (%d)\n",
sc != NULL ? sc->sc_dev.dv_xname : "console", depth);
return (EINVAL);
}
bzero(scr, sizeof *scr);
scr->nsegs = 0;
scr->depth = depth;
scr->buf_size = size;
scr->buf_va = NULL;
size = roundup(size, 16);
#if 0
+ 3 * sizeof (struct lcd_dma_descriptor)
+ palette_size;
#endif
error = bus_dmamem_alloc(dma_tag, size, 0x100000, 0,
scr->segs, 1, &(scr->nsegs), busdma_flag);
if (error != 0 || scr->nsegs != 1) {
if (error == 0)
error = E2BIG;
goto bad;
}
error = bus_dmamem_map(dma_tag, scr->segs, scr->nsegs,
size, (caddr_t *)&(scr->buf_va), busdma_flag | BUS_DMA_COHERENT);
if (error != 0)
goto bad;
memset(scr->buf_va, 0, scr->buf_size);
bcopy(splash, scr->buf_va,
sizeof (splash) > scr->buf_size ? scr->buf_size : sizeof (splash));
if (bus_dmamap_create(dma_tag, 1024 * 1024 * 2, 1,
1024 * 1024 * 2, 0, busdma_flag, &scr->dma))
goto bad;
error = bus_dmamap_load(dma_tag, scr->dma,
scr->buf_va, size, NULL, busdma_flag);
if (error != 0) {
goto bad;
}
scr->map_size = size;
if (sc != NULL) {
LIST_INSERT_HEAD(&(sc->sc_screens), scr, link);
sc->sc_nscreens++;
}
omdisplay_initialize(sc, geometry);
return (0);
bad:
if (scr->buf_va)
bus_dmamem_unmap(dma_tag, scr->buf_va, size);
if (scr->nsegs)
bus_dmamem_free(dma_tag, scr->segs, scr->nsegs);
return (error);
}
paddr_t
omdisplay_mmap(void *v, off_t offset, int prot)
{
struct omdisplay_softc *sc = v;
struct omdisplay_screen *screen = sc->sc_active;
if ((offset & PAGE_MASK) != 0)
return (-1);
if (screen == NULL)
return (-1);
if (offset < 0 ||
offset >= screen->rinfo.ri_stride * screen->rinfo.ri_height)
return (-1);
return (bus_dmamem_mmap(sc->sc_dma_tag, screen->segs, screen->nsegs,
offset, prot, BUS_DMA_WAITOK | BUS_DMA_COHERENT));
}
void
omdisplay_free_screen(void *v, void *cookie)
{
struct omdisplay_softc *sc = v;
struct rasops_info *ri = cookie;
struct omdisplay_screen *scr = ri->ri_hw;
LIST_REMOVE(scr, link);
sc->sc_nscreens--;
if (scr == sc->sc_active) {
sc->sc_active = NULL;
#ifdef DEBUG
printf("lcd_free on active screen\n");
#endif
omdisplay_stop(sc);
}
if (scr->buf_va)
bus_dmamem_unmap(sc->sc_dma_tag, scr->buf_va, scr->map_size);
if (scr->nsegs > 0)
bus_dmamem_free(sc->sc_dma_tag, scr->segs, scr->nsegs);
free(scr, M_DEVBUF, 0);
}
int
omdisplay_load_font(void *v, void *emulcookie, struct wsdisplay_font *font)
{
struct omdisplay_softc *sc = v;
struct omdisplay_screen *scr = sc->sc_active;
if (scr == NULL)
return ENXIO;
return rasops_load_font(scr->rinfo, emulcookie, font);
}
int
omdisplay_list_font(void *v, struct wsdisplay_font *font)
{
struct omdisplay_softc *sc = v;
struct omdisplay_screen *scr = sc->sc_active;
if (scr == NULL)
return ENXIO;
return rasops_list_font(scr->rinfo, font);
}
void
omdisplay_start(struct omdisplay_softc *sc)
{
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_CONTROL,
DISPC_CONTROL_GPOUT0 | DISPC_CONTROL_GPOUT1 |
DISPC_CONTROL_TFTDATALINES_18 |
DISPC_CONTROL_STNTFT |
DISPC_CONTROL_GOLCD |
DISPC_CONTROL_LCDENABLE);
}
void
omdisplay_stop(struct omdisplay_softc *sc)
{
bus_space_write_4(sc->sc_iot, sc->sc_dcioh, DISPC_CONTROL,
bus_space_read_4(sc->sc_iot, sc->sc_dcioh, DISPC_CONTROL) &
~(DISPC_CONTROL_DIGITALENABLE|DISPC_CONTROL_LCDENABLE));
}
int
omdisplay_intr(void *v)
{
return 1;
}