Commit 20154a70 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add initial version of OMAP video driver module

Detail:
  All-new OMAP video driver, written as a module in C.
  Functionality-wise it's basically the same as the original HAL-based driver, except it provides support for GraphicsV_Render via use of the OMAP SDMA controller, and there's currently no support for GraphicsV_IICOp.
  However under the hood the module is significantly different, to ensure it can be expanded to expose the full feature set of the video controller once the new GraphicsV API is ready.
Admin:
  Tested on rev C2 beagleboard.


Version 0.01. Tagged as 'OMAPVideo-0_01'
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * 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.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
Dir <Obey$Dir>
amu_machine standalone
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * 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.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
Dir <Obey$Dir>
amu_machine clean
remove rm.DbgMess
stripdepnd
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * 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.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
Dir <Obey$Dir>
amu_machine export
| Copyright (c) 2010, RISC OS Open Ltd
| All rights reserved.
|
| Redistribution and use in source and binary forms, with or without
| modification, are permitted provided that the following conditions are met:
| * Redistributions of source code must retain the above copyright
| notice, this list of conditions and the following disclaimer.
| * 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.
| * Neither the name of RISC OS Open Ltd nor the names of its contributors
| may be used to endorse or promote products derived from this software
| without specific prior written permission.
|
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
|
Dir <Obey$Dir>
amu_machine rom
c/** gitlab-language=c linguist-language=c linguist-detectable=true
h/** gitlab-language=c linguist-language=c linguist-detectable=true
cmhg/** gitlab-language=cmhg linguist-language=cmhg linguist-detectable=true
Copyright (c) 2010-2017, RISC OS Open Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* 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.
* Neither the name of RISC OS Open Ltd nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
#
# Copyright (c) 2010, RISC OS Open Ltd
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * 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.
# * Neither the name of RISC OS Open Ltd nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
#
# Makefile for OMAP video driver
#
# $Id$
DEBUG ?= FALSE
ifeq ($(DEBUG),TRUE)
CFLAGS += -DDEBUGLIB
CMHFGLAGS += -DDEBUGLIB
LIBS = ${DEBUGLIB} ${MODMALLOCLIB} ${WILDLIB} ${DDTLIB} ${DESKLIB} ${NET5LIBS} ${ASMUTILS} ${TBOXLIBS}
endif
COMPONENT = OMAPVideo
TARGET = ${COMPONENT}
DIRS = o._dirs
OBJS = o.modhead o.cmodule o.regs o.dispc o.dsi o.dss o.venc o.graphicsv o.sdma
CFLAGS += -ff -wp -wc -zm -zps1
CDEFINES += ${CDEBUG}
CMHGDEFINES = -DCOMPONENT=${COMPONENT} ${CDEBUG}
include StdTools
include ModStdRule
include ModuleLibs
include RAMCModule
include ROMCModule
aif.${COMPONENT}: ${RAM_OBJS} ${RAM_LIBS} ${CLIB} o._dirs
link -base 0 -aif -bin -d -o $@ ${RAM_OBJS} ${RAM_LIBS} ${CLIB}
gpa.${COMPONENT}: aif.${COMPONENT}
togpa aif.${COMPONENT} $@
clean:
${WIPE} o ${WFLAGS}
${WIPE} rm ${WFLAGS}
${WIPE} gpa ${WFLAGS}
${WIPE} aif ${WFLAGS}
${RM} h.modhead
o._dirs:
${MKDIR} o
${MKDIR} c
${MKDIR} gpa
${MKDIR} aif
${TOUCH} o._dirs
o.cmodule: h.modhead
# Dynamic dependencies:
/* (0.01)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.01
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 28 Feb 2010
#define Module_MajorVersion "0.01"
#define Module_Version 1
#define Module_MinorVersion ""
#define Module_Date "28 Feb 2010"
#define Module_ApplicationDate "28-Feb-10"
#define Module_ComponentName "OMAPVideo"
#define Module_ComponentPath "bsd/RiscOS/Sources/Video/HWSupport/OMAPVideo"
#define Module_FullVersion "0.01"
#define Module_HelpVersion "0.01 (28 Feb 2010)"
#define Module_LibraryVersionInfo "0:1"
/*
*Copyright(c)2010, RISC OS Open Ltd
*Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "modhead.h"
#include "swis.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "Global/RISCOS.h"
#include "Global/Services.h"
#include "Global/HALDevice.h"
#include "Global/HALEntries.h"
#include "Global/GraphicsV.h"
#include "DebugLib/DebugLib.h"
#include "globals.h"
#include "graphicsv.h"
#include "dss.h"
#include "venc.h"
#include "sdma.h"
void *private_word;
int instance;
vdu_device *dev=0;
uint8_t graphicsv_driver_number = 0;
boardconfig *hwconfig=0;
overlay overlays[OVERLAY_MAX];
u32 dsi_pll_current_pixel_rate=0;
lcdtimings current_timings;
int current_lcd=0;
tvmode current_tvmode = TVMODE_NTSC_601;
tvouttype current_tvtype = TVOUT_NONE;
bool testcard = false;
transparencycfg current_transparencycfgs[TARGET_MAX] = {TRANSPARENCY_TCK_VIDSRC,TRANSPARENCY_TCK_VIDSRC};
overlayidx overlay_desktop = OVERLAY_GFX;
overlayidx overlay_pointer = OVERLAY_VID2;
overlaytarget default_display = TARGET_LCD;
u32 *gfx_palette_l;
u32 gfx_palette_p;
u32 mouse_palette_soft[4];
bool mouse_dirty;
u32 *mouse_image_l;
u32 mouse_image_p;
u8 mouse_image_soft[32*32/4];
const u8 overlay_format_bpp[16] = {1,2,4,8,16,16,16,0,32,24,64,64,32,32,32,0};
const u8 fifo_preload_for_lcd[LCD_MAX] = {0, 0x60, 0x72, 0xE0, 0xE0};
const u32 transparency_lut[TARGET_MAX][TRANSPARENCY_MAX] =
{
{
0,
DISPC_CONFIG_TCKLCDENABLE | DISPC_CONFIG_TCKLCDSELECTION,
DISPC_CONFIG_TCKLCDENABLE,
DISPC_CONFIG_TCKLCDENABLE | DISPC_CONFIG_LCDALPHABLENDERENABLE,
DISPC_CONFIG_LCDALPHABLENDERENABLE,
},
{
0,
DISPC_CONFIG_TCKDIGENABLE | DISPC_CONFIG_TCKDIGSELECTION,
DISPC_CONFIG_TCKDIGENABLE,
DISPC_CONFIG_TCKDIGENABLE | DISPC_CONFIG_TVALPHABLENDERENABLE,
DISPC_CONFIG_TVALPHABLENDERENABLE,
},
};
int exp_synclost_count=0;
_kernel_oserror* module_init (const char *cmd_tail, int podule_base, void *pw)
{
_kernel_oserror* e = 0;
u32 mask=0;
/* set up debugging */
debug_initialise(Module_Title, "", "");
// debug_set_options(2,0,115200);
// debug_set_device(SERIAL_OUTPUT);
// debug_set_device(DADEBUG_OUTPUT);
debug_set_device(PRINTF_OUTPUT);
debug_set_unbuffered_files(TRUE);
instance = podule_base;
private_word = pw;
/* Hunt for the HAL device */
int pos=0;
do {
e = _swix(OS_Hardware, _INR(0,1) | _IN(8) | _OUTR(1,2), HALDeviceType_Video + HALDeviceVideo_VDU,pos,4,&pos,&dev);
if(e)
goto error;
if(pos == -1)
{
return (_kernel_oserror*) "\0\0\0\0No OMAP video devices found";
}
} while(dev->dev.id != HALDeviceID_VDU_OMAP3);
/* Call the Activate entry to turn on the clocks and make sure everything's OK */
if(!(dev->dev.Activate)(&dev->dev))
{
return (_kernel_oserror*) "\0\0\0\0Video device failed to activate";
}
/* Get boardconfig/hwconfig struct */
hwconfig = (boardconfig *) dev->devicespecificfield;
/* Make sure overlays are marked as disabled */
for(int i=0;i<OVERLAY_MAX;i++)
{
memset(&overlays[i],0,sizeof(overlay));
overlays[i].target = TARGET_NONE;
}
/* Get hardware addresses */
dss = (dss_regs *) dev->dev.address;
dispc = (dispc_regs *) (((u32)dev->dev.address)+0x400);
rfbi = (rfbi_regs *) (((u32)dev->dev.address)+0x800);
venc = (venc_regs *) (((u32)dev->dev.address)+0xc00);
dsi = (dsi_regs *) (((u32)dev->dev.address)-0x400);
dsi_phy = (dsi_phy_regs *) (((u32)dev->dev.address)-0x200);
dsi_pll = (dsi_pll_regs *) (((u32)dev->dev.address)-0x100);
sdma = hwconfig->dma_ptr;
/* Get address of the sole DMA channel we use */
mask = hwconfig->dma_chans;
if(mask)
{
sdmachan = &sdma->chans[0];
while(!(mask & 1))
{
sdmachan++;
mask = mask>>1;
}
dprintf(("","Using DMA channel at %08x\n",sdmachan));
/* Make sure channel is in a sane state */
sdma_sync();
sdmachan->clnk_ctrl = 0;
sdmachan->cicr = 0;
}
else
sdmachan = 0;
/* Perform a reset so that we can safely enable IRQs */
e = dss_reset();
if(e)
goto error2;
/* Get some workspace from the PCI module */
e = _swix(PCI_RAMAlloc, _INR(0,2) | _OUTR(0,1), 4*256+32*32*4, 32, 0, &gfx_palette_l, &gfx_palette_p);
if(e)
goto error2;
mouse_image_l = gfx_palette_l + 256;
mouse_image_p = gfx_palette_p + 256*4;
/* Claim & enable */
e = _swix (OS_ClaimDeviceVector, _INR(0,4), dev->dev.devicenumber, dispc_irq_entry, pw, 0, 0);
if(e)
goto error3;
e = _swix (OS_Hardware, _IN(0) | _INR(8,9), dev->dev.devicenumber&~(1u<<31), 0, EntryNo_HAL_IRQEnable);
if(e)
goto error4;
/* Get on GraphicsV! */
e = _swix(OS_Claim, _INR(0,2), GraphicsV, graphicsv_entry, pw);
if(e)
goto error4;
dprintf(("", "Finished module initialisation, DSS regs=%08x\n",(u32)dss));
return 0;
error4:
/* Release IRQ */
_swix (OS_ReleaseDeviceVector, _INR(0,4), dev->dev.devicenumber, dispc_irq_entry, pw, 0, 0);
error3:
/* Release memory */
_swix(PCI_RAMFree, _IN(0), gfx_palette_l);
gfx_palette_l = mouse_image_l = NULL;
gfx_palette_p = mouse_image_p = 0;
error2:
/* Deactivate */
(dev->dev.Deactivate)(&dev->dev);
dev = 0;
error:
dprintf(("","Failed initialisation: %s\n", e->errmess));
return e;
}
_kernel_oserror *module_final(int fatal, int podule, void *pw)
{
_kernel_oserror* e = 0;
_swix(OS_Release, _INR(0,2), GraphicsV, graphicsv_entry, pw);
if(dev)
{
e = _swix (OS_ReleaseDeviceVector, _INR(0,4), dev->dev.devicenumber, dispc_irq_entry, pw, 0, 0);
if(e)
return e;
(dev->dev.Deactivate)(&dev->dev);
dev = 0;
}
if(gfx_palette_l)
{
e = _swix(PCI_RAMFree, _IN(0), gfx_palette_l);
if(e)
return e;
gfx_palette_l = mouse_image_l = NULL;
gfx_palette_p = mouse_image_p = 0;
}
return NULL;
}
#ifdef DEBUGLIB
extern int sdma_stats[4];
#define DUMPREG(BANK,REG) printf("%08x: %08x %s.%s\n",(u32) &(BANK->REG),BANK->REG,#BANK,#REG)
_kernel_oserror *module_commands(const char *arg_string, int argc, int cmd_no, void *pw)
{
switch (cmd_no) {
case CMD_VideoRegs:
DUMPREG(dss,sysconfig);
DUMPREG(dss,sysstatus);
DUMPREG(dss,irqstatus);
DUMPREG(dss,control);
DUMPREG(dss,sdi_control);
DUMPREG(dss,pll_control);
DUMPREG(dss,sdi_status);
DUMPREG(dispc,sysconfig);
DUMPREG(dispc,sysstatus);
DUMPREG(dispc,irqstatus);
DUMPREG(dispc,irqenable);
DUMPREG(dispc,control);
DUMPREG(dispc,config);
DUMPREG(dispc,default_color[0]);
DUMPREG(dispc,default_color[1]);
DUMPREG(dispc,trans_color[0]);
DUMPREG(dispc,trans_color[1]);
DUMPREG(dispc,line_status);
DUMPREG(dispc,line_number);
DUMPREG(dispc,timing_h);
DUMPREG(dispc,timing_v);
DUMPREG(dispc,pol_freq);
DUMPREG(dispc,divisor);
DUMPREG(dispc,global_alpha);
DUMPREG(dispc,size_dig);
DUMPREG(dispc,size_lcd);
DUMPREG(dispc,gfx.ba[0]);
DUMPREG(dispc,gfx.ba[1]);
DUMPREG(dispc,gfx.position);
DUMPREG(dispc,gfx.size);
DUMPREG(dispc,gfx.attributes);
DUMPREG(dispc,gfx.fifo_threshold);
DUMPREG(dispc,gfx.fifo_size_status);
DUMPREG(dispc,gfx.row_inc);
DUMPREG(dispc,gfx.pixel_inc);
DUMPREG(dispc,gfx.window_skip);
DUMPREG(dispc,gfx.table_ba);
DUMPREG(dispc,vid1.ba[0]);
DUMPREG(dispc,vid1.ba[1]);
DUMPREG(dispc,vid1.position);
DUMPREG(dispc,vid1.size);
DUMPREG(dispc,vid1.attributes);
DUMPREG(dispc,vid1.fifo_threshold);
DUMPREG(dispc,vid1.fifo_size_status);
DUMPREG(dispc,vid1.row_inc);
DUMPREG(dispc,vid1.pixel_inc);
DUMPREG(dispc,vid1.fir);
DUMPREG(dispc,vid1.picture_size);
// DUMPREG(dispc,vid1.accui[0]);
// DUMPREG(dispc,vid1.accui[1]);
// DUMPREG(dispc,vid1.fir_coef[0].h);
// DUMPREG(dispc,vid1.fir_coef[0].hv);
// DUMPREG(dispc,vid1.fir_coef[1].h);
// DUMPREG(dispc,vid1.fir_coef[1].hv);
// DUMPREG(dispc,vid1.fir_coef[2].h);
// DUMPREG(dispc,vid1.fir_coef[2].hv);
// DUMPREG(dispc,vid1.fir_coef[3].h);
// DUMPREG(dispc,vid1.fir_coef[3].hv);
// DUMPREG(dispc,vid1.fir_coef[4].h);
// DUMPREG(dispc,vid1.fir_coef[4].hv);
// DUMPREG(dispc,vid1.fir_coef[5].h);
// DUMPREG(dispc,vid1.fir_coef[5].hv);
// DUMPREG(dispc,vid1.fir_coef[6].h);
// DUMPREG(dispc,vid1.fir_coef[6].hv);
// DUMPREG(dispc,vid1.fir_coef[7].h);
// DUMPREG(dispc,vid1.fir_coef[7].hv);
// DUMPREG(dispc,vid1.conv_coef[0]);
// DUMPREG(dispc,vid1.conv_coef[1]);
// DUMPREG(dispc,vid1.conv_coef[2]);
// DUMPREG(dispc,vid1.conv_coef[3]);
// DUMPREG(dispc,vid1.conv_coef[4]);
DUMPREG(dispc,vid2.ba[0]);
DUMPREG(dispc,vid2.ba[1]);
DUMPREG(dispc,vid2.position);
DUMPREG(dispc,vid2.size);
DUMPREG(dispc,vid2.attributes);
DUMPREG(dispc,vid2.fifo_threshold);
DUMPREG(dispc,vid2.fifo_size_status);
DUMPREG(dispc,vid2.row_inc);
DUMPREG(dispc,vid2.pixel_inc);
DUMPREG(dispc,vid2.fir);
DUMPREG(dispc,vid2.picture_size);
// DUMPREG(dispc,vid2.accui[0]);
// DUMPREG(dispc,vid2.accui[1]);
// DUMPREG(dispc,vid2.fir_coef[0].h);
// DUMPREG(dispc,vid2.fir_coef[0].hv);
// DUMPREG(dispc,vid2.fir_coef[1].h);
// DUMPREG(dispc,vid2.fir_coef[1].hv);
// DUMPREG(dispc,vid2.fir_coef[2].h);
// DUMPREG(dispc,vid2.fir_coef[2].hv);
// DUMPREG(dispc,vid2.fir_coef[3].h);
// DUMPREG(dispc,vid2.fir_coef[3].hv);
// DUMPREG(dispc,vid2.fir_coef[4].h);
// DUMPREG(dispc,vid2.fir_coef[4].hv);
// DUMPREG(dispc,vid2.fir_coef[5].h);
// DUMPREG(dispc,vid2.fir_coef[5].hv);
// DUMPREG(dispc,vid2.fir_coef[6].h);
// DUMPREG(dispc,vid2.fir_coef[6].hv);
// DUMPREG(dispc,vid2.fir_coef[7].h);
// DUMPREG(dispc,vid2.fir_coef[7].hv);
// DUMPREG(dispc,vid2.conv_coef[0]);
// DUMPREG(dispc,vid2.conv_coef[1]);
// DUMPREG(dispc,vid2.conv_coef[2]);
// DUMPREG(dispc,vid2.conv_coef[3]);
// DUMPREG(dispc,vid2.conv_coef[4]);
DUMPREG(dispc,data_cycle[0]);
DUMPREG(dispc,data_cycle[1]);
DUMPREG(dispc,data_cycle[2]);
DUMPREG(dispc,cpr_coef_r);
DUMPREG(dispc,cpr_coef_g);
DUMPREG(dispc,cpr_coef_b);
DUMPREG(dispc,gfx_preload);
DUMPREG(dispc,vid_preload[0]);
DUMPREG(dispc,vid_preload[1]);
DUMPREG(dsi_pll,control);
DUMPREG(dsi_pll,status);
DUMPREG(dsi_pll,go);
DUMPREG(dsi_pll,configuration1);
DUMPREG(dsi_pll,configuration2);
printf("Ban state: %08x\n",ban_hardware_update);
break;
case CMD_TVMode:
{
char *str;
int mode = strtoul(arg_string,&str,10);
int type = strtoul(str,&str,10);
int testmode = strtoul(str,0,10);
venc_set_tvmode((tvmode) mode,(tvouttype) type,(bool) testmode);
}
break;
case CMD_TVRegs:
DUMPREG(venc,status);
DUMPREG(venc,f_control);
DUMPREG(venc,vidout_ctrl);
DUMPREG(venc,sync_ctrl);
DUMPREG(venc,llen);
DUMPREG(venc,flens);
DUMPREG(venc,hfltr_ctrl);
DUMPREG(venc,cc_carr_wss_carr);
DUMPREG(venc,c_phase);
DUMPREG(venc,gain_u);
DUMPREG(venc,gain_y);
DUMPREG(venc,gain_v);
DUMPREG(venc,black_level);
DUMPREG(venc,blank_level);
DUMPREG(venc,x_color);
DUMPREG(venc,m_control);
DUMPREG(venc,bstamp_wss_data);
DUMPREG(venc,s_carr);
DUMPREG(venc,line21);
DUMPREG(venc,ln_sel);
DUMPREG(venc,l21_wc_ctl);
DUMPREG(venc,htrigger_vtrigger);
DUMPREG(venc,savid_eavid);
DUMPREG(venc,flen_fal);
DUMPREG(venc,lal_phase_reset);
DUMPREG(venc,hs_int_start_stop_x);
DUMPREG(venc,hs_ext_start_stop_x);
DUMPREG(venc,vs_int_start_x);
DUMPREG(venc,vs_int_stop_x_vs_int_start_y);
DUMPREG(venc,vs_int_stop_y_vs_ext_start_x);
DUMPREG(venc,vs_ext_stop_x_vs_ext_start_y);
DUMPREG(venc,vs_ext_stop_y);
DUMPREG(venc,avid_start_stop_x);
DUMPREG(venc,avid_start_stop_y);
DUMPREG(venc,fid_int_start_x_fid_int_start_y);
DUMPREG(venc,fid_int_offset_y_fid_ext_start_x);
DUMPREG(venc,fid_ext_start_y_fid_ext_offset_y);
DUMPREG(venc,tvdetgp_int_start_stop_x);
DUMPREG(venc,tvdetgp_int_start_stop_y);
DUMPREG(venc,gen_ctrl);
DUMPREG(venc,output_control);
DUMPREG(venc,output_test);
DUMPREG(dispc,control);
DUMPREG(dss,control);
break;
case CMD_TVOut:
{
int mode = strtoul(arg_string,0,10);
default_display = (mode?TARGET_TV:TARGET_LCD);
/* Don't bother with hardware update for now */
}
break;
case CMD_SDMARegs:
DUMPREG(sdma,irqstatus[0]);
DUMPREG(sdma,irqstatus[1]);
DUMPREG(sdma,irqstatus[2]);
DUMPREG(sdma,irqstatus[3]);
DUMPREG(sdma,irqenable[0]);
DUMPREG(sdma,irqenable[1]);
DUMPREG(sdma,irqenable[2]);
DUMPREG(sdma,irqenable[3]);
DUMPREG(sdma,sysstatus);
DUMPREG(sdma,ocp_sysconfig);
DUMPREG(sdma,gcr);
DUMPREG(sdmachan,ccr);
DUMPREG(sdmachan,clnk_ctrl);
DUMPREG(sdmachan,cicr);
DUMPREG(sdmachan,csr);
DUMPREG(sdmachan,csdp);
DUMPREG(sdmachan,cen);
DUMPREG(sdmachan,cfn);
DUMPREG(sdmachan,cssa);
DUMPREG(sdmachan,cdsa);
DUMPREG(sdmachan,csei);
DUMPREG(sdmachan,csfi);
DUMPREG(sdmachan,cdei);
DUMPREG(sdmachan,cdfi);
DUMPREG(sdmachan,csac);
DUMPREG(sdmachan,cdac);
DUMPREG(sdmachan,ccen);
DUMPREG(sdmachan,ccfn);
DUMPREG(sdmachan,color);
printf("%d fills\n%d copy 1\n%d copy 2\n%d copy 3\n",sdma_stats[0],sdma_stats[1],sdma_stats[2],sdma_stats[3]);
memset(sdma_stats,0,sizeof(sdma_stats));
break;
}
return 0;
}
#endif
This diff is collapsed.
/*
*Copyright(c)2010, RISC OS Open Ltd
*Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "dsi.h"
#include "dss.h"
#include "globals.h"
#include "regs.h"
#include "DebugLib/DebugLib.h"
/* TODO - This should be moved somewhere more sensible */
typedef struct {
u32 min,max;
u8 freqsel;
} freqsel_range;
freqsel_range freqsel_table[] = {
{ 750000, 1000000, 0x3 },
{ 1000000, 1250000, 0x4 },
{ 1250000, 1500000, 0x5 },
{ 1500000, 1750000, 0x6 },
{ 1750000, 2100000, 0x7 },
{ 7500000, 10000000, 0xB },
{ 10000000, 12500000, 0xC },
{ 12500000, 15000000, 0xD },
{ 15000000, 17500000, 0xE },
{ 17500000, 21000000, 0xF },
{ 0, 0xFFFFFFFF, 0 } /* List terminator is catch-all for error case */
};
u8 get_freqsel(u32 Fint)
{
freqsel_range *r = freqsel_table;
while((Fint < r->min) || (r->max < Fint))
r++;
return r->freqsel;
}
#ifdef DEBUGLIB
static const char *cmds[4] = {"OFF","DSI_PLL_ON_HSDIVIDER_OFF","BOTH_ON","BOTH_ON_DSI_COMPLEXIO_OFF"};
#endif
void dsi_pll_command(u32 cmd)
{
dsi->clk_ctrl = (dsi->clk_ctrl & ~DSI_CLK_CTRL_PLL_PWR_CMD_MASK) | (cmd<<DSI_CLK_CTRL_PLL_PWR_CMD_SHIFT);
int timeout=1000000;
while(((dsi->clk_ctrl & DSI_CLK_CTRL_PLL_PWR_STATUS_MASK)>>DSI_CLK_CTRL_PLL_PWR_STATUS_SHIFT != cmd) && timeout--) {};
if(!timeout)
{
dprintf(("","dsi_pll_command: Timeout waiting for cmd %s; current state %s\n",cmds[cmd],cmds[(dsi->clk_ctrl & DSI_CLK_CTRL_PLL_PWR_STATUS_MASK)>>DSI_CLK_CTRL_PLL_PWR_STATUS_SHIFT]));
}
}
void dsi_pll_program_for_dispc(u32 pixel_rate)
{
/* Program the DSI PLL for use by DISPC */
if(pixel_rate == dsi_pll_current_pixel_rate)
return;
clock_divider div = calculate_dss_clock_divider(pixel_rate);
dprintf(("","dsi_pll_program_for_dispc: Changing pixel rate from %d to %d\n",dsi_pll_current_pixel_rate,pixel_rate));
dprintf(("","REGM=%d REGN=%d\n",div.regm,div.regn));
/* TODO - Need to reset DSI as per 15.6.3.2.1 p2364? Or at least work out some other correct way of reprogramming it when it's already running */
/* Set up DSI PLL, as per spruf98d 15.6.3.2.2 p2364 (with some fairly important modifications!) */
/* 1. Turn on PLL & HSDIVIDER
2. Wait for response */
dsi_pll_command(DSI_PLL_PWR_CMD_BOTH_ON);
/* 3-6. Program configuration1 register (according to spruf98d fig 15-139 (p2318)) */
/* TODO - error on invalid */
u32 config1,config2;
config2 = 0; /* We want DSI_PLL_CLKSEL clear so the PLL uses SYS_CLK as its source */
/* TODO - Remove assumption that SYS_CLK <32MHz? */
config1 = div.regn << DSI_PLL_CONFIGURATION1_DSI_PLL_REGN_SHIFT;
config1 |= div.regm << DSI_PLL_CONFIGURATION1_DSI_PLL_REGM_SHIFT;
/* REGM3+1 = frequency on data lane/(pixel rate*2)
REGM3+1 = (2*pixel rate*bpp)/(pixel rate*2*lanes) = DSI_BPP/DSI_LANES */
lcdconfig *config = &hwconfig->lcd_configs[current_lcd];
config1 |= ((config->dsi_bpp/config->dsi_lanes)-1)<<DSI_PLL_CONFIGURATION1_DSS_CLOCK_DIV_SHIFT;
/* REGM4 unused, so leave as 0 */
config1 |= 7<<DSI_PLL_CONFIGURATION1_DSIPROTO_CLOCK_DIV_SHIFT; /* TODO - EXPERIMENT - Sort out REGM4 */
/* 7. Enable PLLStopMode */
config1 |= DSI_PLL_CONFIGURATION1_DSI_PLL_STOPMODE;
/* 8. Program configuration2 register */
/* Calculate Fint so we can get freqsel value */
u32 Fint = hwconfig->sys_clk/(div.regn+1);
dprintf(("","Fint=%d\n",Fint));
config2 |= get_freqsel(Fint) << DSI_PLL_CONFIGURATION2_DSI_PLL_FREQSEL_SHIFT;
/* Other flags - only REFEN & DSS_CLOCK_EN are needed from the example. However we also use the drift guard, so enable that. */
config2 |= DSI_PLL_CONFIGURATION2_DSI_PLL_REFEN | DSI_PLL_CONFIGURATION2_DSS_CLOCK_EN | DSI_PLL_CONFIGURATION2_DSI_PLL_DRIFTGUARDEN;
/* 9. Select manual mode (and program config1, config2) */
dsi_pll->configuration1 = config1;
dsi_pll->configuration2 = config2;
dsi_pll->control = 0;
/* 10. Lock */
dsi_pll->go = DSI_PLL_GO_DSI_PLL_GO;
/* 11. Wait for GO bit to clear */
int timeout=1000000;
while((dsi_pll->go & DSI_PLL_GO_DSI_PLL_GO) && timeout--) {};
if(!timeout)
{
dprintf(("","dsi_pll_program_for_dispc: Timeout waiting for DSI_PLL_GO\n"));
}
/* 12. Wait for PLL to lock */
timeout=1000000;
while(!(dsi_pll->status & DSI_PLL_STATUS_DSI_PLL_CLOCK) && timeout--) {};
if(!timeout)
{
dprintf(("","dsi_pll_program_for_dispc: Timeout waiting for DSI_PLL_CLOCK\n"));
}
/* 13. Turn on PLL & HSDIVIDER - Should already be on? And the rest of the stuff is irrelevant, since we don't use DSI */
/* TODO - EXPERIMENT - Enable HSDIVIDER in bypass mode, as per HAL code (needs moving to before lock?) */
// config2 |= DSI_PLL_CONFIGURATION2_DSI_PLL_HSDIVBYPASS;
/* Done! */
dsi_pll_current_pixel_rate = pixel_rate;
dprintf(("","dsi_pll_program_for_dispc: Done\n"));
}
/*
 * Copyright (c) 2010, RISC OS Open Ltd
 * All rights reserved.
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "dss.h"
#include "regs.h"
#include "globals.h"
#include "DebugLib/DebugLib.h"
_kernel_oserror *dss_reset(void)
{
/* Perform system reset as per spruf98d 15.5.1 */
/* Except we'll skip the LCD reset for now, since the method they describe could fail if we don't use a timeout (if FRAMEDONE goes to 1 before we get a chance to clear it) */
/* Plus the clocks are already enabled, so all we need to do is the soft reset */
dprintf(("","dss_reset\n"));
dss->sysconfig = SYSCONFIG_SOFTRESET;
int timeout=1000000;
while(!(dss->sysstatus & SYSSTATUS_RESETDONE) && --timeout) {};
if(!timeout)
{
dprintf(("","dss_reset: Timeout waiting for SYSSTATUS_RESETDONE!\n"));
}
/* EXPERIMENT: Enable venc clocks? */
dss->control = DSS_CONTROL_VENC_CLOCK_4X_ENABLE | DSS_CONTROL_DAC_DEMEN | DSS_CONTROL_DAC_POWERDN_BGZ | DSS_CONTROL_VENC_OUT_SEL;
/* DSS reset also causes DSI PLL reset */
dsi_pll_current_pixel_rate = 0;
/* Clear ban flag? */
clear_ban(BHUB_OFF);
return 0;
}
clock_divider calculate_dss_clock_divider(u32 pixel_rate)
{
/* Calculate DSI_PLL_REGM, DSI_PLL_REGN values required for the given pixel rate (in Hz)
Output values aren't guaranteed to be within range
The full clock flow is as follows:
DSI PLL input = DSI_PLL_REFCLK (= DSS2_ALWON_FCLK = sys_clk)
Data lane freq = DSIPHY = 2*pixel rate*DSI_BPP/DSI_LANES
DSIPHY = 2*DSI_PLL_REGM/(DSI_PLL_REGN+1)*DSI_PLL_REFCLK/(HIGHFREQ+1)
HIGHFREQ = (DSI_PLL_REFCLK>32MHz?1:0) (=0 for all current sys_clk values)
Also, 0.75MHz <= Fint <= 2.1MHz where Fint = DSI_PLL_REFCLK/(DSI_PLL_REGN+1)
DSIPHY is then used as the source for the HSDIVIDER, which does the following:
DSI1_PLL_FCLK = DSIPHY/REGM3
DSI2_PLL_FCLK = DSIPHY/REGM4
Both must be <= 173MHz
DSI2_PLL_FCLK can be used to drive the DSI module, except we don't care much for that
DSI1_PLL_FCLK is what we use to drive the DISPC pixel clock:
pixel rate = (DSI1_PLL_FCLK/LCD)/PCD
1 <= LCD <= 255
2 <= PCD <= 255
Even though we don't use the DSI output module, we still calculate DSIPHY as if we are using it (so that DSIPHY = data lane freq)
This then simplifies REGM3, REGM4, LCD and PCD programming so that it can use fixed values independent of the pixel rate:
REGM3 = DSIPHY/(pixel rate*2) = DSI_LANES/DSI_BPP (so that DSI1_PLL_FCLK = 2*pixel rate)
LCD=1, PCD=2 (so that DSI1_PLL_FCLK is divided by two to get the target pixel rate)
An algorithm that aims for 100% accurate clock rates was found to be incapable of calculating divider values for most RISC OS screen modes (in particular the 25.175MHz mode used at boot). Instead, an algorithm that aims to find the closest possible clock rate is used. Most clock rate errors appear to be tiny (within 1kHz of the desired data lane frequency), so this shouldn't pose any problems. */
clock_divider best;
best.regm = 0;
best.regn = -1;
if(!pixel_rate)
{
return best;
}
/* Data lane freq = 2*pixel rate*bpp/lanes */
lcdconfig *config = &hwconfig->lcd_configs[current_lcd];
u32 data_lane_freq = (2*pixel_rate*config->dsi_bpp)/config->dsi_lanes; /* TODO - Could get rid of the division (and thus make safe against noninteger results) by moving it over to the REGM calculation stage? */
u32 best_error = data_lane_freq; /* Best error. This can easily be modified to limit the clock to a maximum error value, either fixed or to within a percentage of the pixel rate. */
/* Search for satisfactory regn:
- Provides Fint that's within range
- sys_clk MOD REGN = 0
*/
clock_divider current;
current.regn = 1; /* Current N(+1) */
do
{
u32 Fint = hwconfig->sys_clk/current.regn;
if(!(hwconfig->sys_clk % current.regn) && (Fint >= 750000) && (Fint <= 2100000))
{
/* REGN is good; use it to calculate nearest REGM */
current.regm = data_lane_freq/(Fint*2);
u32 error = data_lane_freq % (Fint*2);
/* Rount to nearest, maintaining a2 as the error */
if(error >= Fint)
{
current.regm++;
error = (Fint*2)-error;
}
/* Is it better? */
if(error < best_error)
{
best_error = error;
best.regm = current.regm;
best.regn = current.regn-1;
}
/* Is it perfect? */
if(!error)
return best;
}
} while(++current.regn <= REG_MAX(DSI_PLL_CONFIGURATION1_DSI_PLL_REGN)+1);
return best;
}
/*
*Copyright(c)2010, RISC OS Open Ltd
*Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "modhead.h"
#include "swis.h"
#include "Global/RISCOS.h"
#include "Global/Services.h"
#include "Global/HALEntries.h"
#include "Global/GraphicsV.h"
#include "DebugLib/DebugLib.h"
#include "regs.h"
#include "videodevice.h"
#include "graphicsv.h"
#include "globals.h"
#include "dispc.h"
#include "dss.h"
#include "venc.h"
#include "sdma.h"
static int do_null(_kernel_swi_regs *r)
{
/* Nothing */
return 0;
}
static int do_vsync(_kernel_swi_regs *r)
{
/* Nothing */
return 1;
}
static int do_setmode(_kernel_swi_regs *r)
{
/* TODO - Needs updating for TV output */
/* TODO - Needs updating for display rotation, etc. */
/* TODO - Should verify mode and then abort if it's bad? */
/* TODO - Should take into account fixed LCD */
/* TODO - Need to decide what to do with border */
/* TODO - How best to ensure atomicity? */
r->r[4] = 0;
vidclist3 *params = (vidclist3 *) r->r[0];
/* Disable any overlays that are currently using the default display? */
for(int i=0;i<OVERLAY_MAX;i++)
if(overlays[i].target == default_display)
overlays[i].target = TARGET_NONE;
/* Update (but don't apply) main overlay */
overlay *o = &overlays[overlay_desktop];
o->width = params->HorizDisplaySize;
o->height = params->VertiDisplaySize;
o->x = 0;
o->y = 0;
switch(params->PixelDepth)
{
case VIDCLIST3_1BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_BMP1;
break;
case VIDCLIST3_2BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_BMP2;
break;
case VIDCLIST3_4BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_BMP4;
break;
case VIDCLIST3_8BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_BMP8;
break;
case VIDCLIST3_16BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_RGB16;
break;
case VIDCLIST3_32BPP:
o->format = OVERLAY_ATTRIBUTES_FORMAT_RGB24_32;
break;
}
o->stride = (o->width*overlay_format_bpp[o->format>>OVERLAY_ATTRIBUTES_FORMAT_SHIFT])>>3;
o->target = default_display;
/* Now set the mode, which will also re-apply overlay settings */
exp_synclost_count=0;
if(default_display == TARGET_LCD)
{
if(hwconfig->lcd_configs[current_lcd].lcd_timings)
{
/* Use fixed timings */
dispc_set_lcdmode(hwconfig->lcd_configs[current_lcd].lcd_timings);
}
else
{
/* Build lcdtimings struct ready for setting mode */
lcdtimings timings;
timings.pixelrate = params->PixelRate*1000;
timings.hsw = params->HorizSyncWidth;
if(timings.hsw > hwconfig->max_sync)
{
dprintf(("","do_setmode: Clamping HSW %d -> %d\n",timings.hsw,hwconfig->max_sync));
timings.hsw = hwconfig->max_sync;
}
timings.hfp = params->HorizFrontPorch;
if(timings.hfp > hwconfig->max_porch)
{
dprintf(("","do_setmode: Clamping HFP %d -> %d\n",timings.hfp,hwconfig->max_porch));
timings.hfp = hwconfig->max_porch;
}
timings.hbp = params->HorizBackPorch;
if(timings.hbp > hwconfig->max_porch)
{
dprintf(("","do_setmode: Clamping HBP %d -> %d\n",timings.hbp,hwconfig->max_porch));
timings.hbp = hwconfig->max_porch;
}
timings.width = params->HorizDisplaySize;
timings.vsw = params->VertiSyncWidth;
if(timings.vsw > hwconfig->max_sync)
{
dprintf(("","do_setmode: Clamping VSW %d -> %d\n",timings.vsw,hwconfig->max_sync));
timings.vsw = hwconfig->max_sync;
}
timings.vfp = params->VertiFrontPorch;
if(timings.vfp >= hwconfig->max_porch)
{
dprintf(("","do_setmode: Clamping VFP %d -> %d\n",timings.vfp,hwconfig->max_porch-1));
timings.vfp = hwconfig->max_porch-1;
}
timings.vbp = params->VertiBackPorch;
if(timings.vbp >= hwconfig->max_porch)
{
dprintf(("","do_setmode: Clamping VBP %d -> %d\n",timings.vbp,hwconfig->max_porch-1));
timings.vbp = hwconfig->max_porch-1;
}
timings.height = params->VertiDisplaySize;
timings.syncpol = params->SyncPol;
dispc_set_lcdmode(&timings);
}
}
else
{
venc_set_tvmode(current_tvmode,current_tvtype,false);
}
return 0;
}
static int do_setinterlace(_kernel_swi_regs *r)
{
/* TODO! */
return 0;
}
static int do_setblank(_kernel_swi_regs *r)
{
/* TODO! */
return 0;
}
static int do_updatepointer(_kernel_swi_regs *r)
{
/* TODO - Needs updating for TV output */
/* TODO - What if palette change isn't immediately followed by an updatepointer call? Need to stick something in IRQ handler that does a secondary update on vsync */
/* TODO - Turn IRQs off at this level to avoid overlay array corruption? */
/* TODO - Needs updating for alpha blending instead of TCK */
shape_t *shape = ((shape_t *) r->r[3]);
r->r[4] = 0;
if(r->r[0] & 1)
{
/* Redo palette if needed */
int dirty = 32*32/4; /* Number of dirty bytes */
u8 *src = (u8 *) shape->buffLA;
u8 *dest = mouse_image_soft;
u32 *real = mouse_image_l;
int incount=shape->height*32/4; /* Number of bytes left in input */
if(incount > dirty)
incount = dirty; /* Protect against dodgy heights */
if(mouse_dirty)
{
u32 trans = mouse_palette_soft[0];
while((trans == mouse_palette_soft[1]) || (trans == mouse_palette_soft[2]) || (trans == mouse_palette_soft[3]))
trans = (trans+1)&0xffffff;
mouse_palette_soft[0] = dispc->trans_color[0] = dispc->trans_color[1] = trans;
}
else if(r->r[0] & 2)
{
while(incount>0)
{
if(*((u32 *)src) != *((u32 *)dest)) /* Check words for speed */
goto rebuild;
src+=4;
dest+=4;
real+=16;
dirty-=4;
incount-=4;
}
while(dirty>0)
{
if(*((u32 *)dest))
goto rebuild;
dest+=4;
real+=16;
dirty-=4;
}
}
/* Redo image if needed
Note that we always pad it out to 32x32; should make life easier once we have rotation support */
/* TODO - Make faster - test each individual byte to see if it matches dest - should speed up most stuff where only small portions change (e.g. ourglass) */
if(mouse_dirty)
{
rebuild:
while(dirty-->0)
{
u8 data = (incount-->0?*src++:0);
*dest++ = data;
*real++ = mouse_palette_soft[data & 3];
data = data >> 2;
*real++ = mouse_palette_soft[data & 3];
data = data >> 2;
*real++ = mouse_palette_soft[data & 3];
data = data >> 2;
*real++ = mouse_palette_soft[data];
}
mouse_dirty = false;
}
/* Redo position & other overlay attribs if needed */
overlay *o = &overlays[overlay_pointer];
if((o->x != r->r[1]) || (o->y != r->r[2]) || (o->target != default_display))
{
o->width = 32;
o->height = 32;
o->x = r->r[1]+overlays[overlay_desktop].x;
o->y = r->r[2]+overlays[overlay_desktop].y;
o->format = OVERLAY_ATTRIBUTES_FORMAT_RGB24_32;
o->ba = mouse_image_p;
o->stride = 32*4;
o->la = (u8 *) mouse_image_l; /* Not really needed */
o->target = default_display;
dispc_update_overlay(overlay_pointer);
}
}
else if(overlays[overlay_pointer].target != TARGET_NONE)
{
overlays[overlay_pointer].target = TARGET_NONE;
dispc_update_overlay(overlay_pointer);
}
return 0;
}
static int do_setdmaaddress(_kernel_swi_regs *r)
{
/* TODO - Needs updating for interlace */
if(r->r[0] == 0)
{
/* IRQs off for atomicity (mainly for dispc->control write) */
int irqs = _kernel_irqs_disabled();
if(!irqs)
_kernel_irqs_off();
u32 ba = overlays[overlay_desktop].ba = r->r[1];
if(overlays[overlay_desktop].target != TARGET_NONE)
{
dispc->gfx.ba[1] = ba;
dispc->gfx.ba[0] = ba + (overlays[overlay_desktop].target == TARGET_TV?overlays[overlay_desktop].stride:0);
if(!ban_hardware_update)
dispc->control |= ((overlays[overlay_desktop].target == TARGET_LCD)?DISPC_CONTROL_GOLCD:DISPC_CONTROL_GODIGITAL);
}
if(!irqs)
_kernel_irqs_on();
}
r->r[4] = 0;
return 0;
}
static int do_vetmode(_kernel_swi_regs *r)
{
/* TODO - Needs updating for TV output */
/* TODO - Needs updating for if using video overlay instead of graphics, display rotation, etc. */
r->r[4] = 0;
vidclist3 *params = (vidclist3 *) r->r[0];
/* For the moment, ignore the mode timings if we're using TV out or fixed LCD */
if((overlays[default_display].target != TARGET_TV) && (hwconfig->lcd_configs[current_lcd].max_pixelrate != 0))
{
/* Check pixel rate */
if(params->PixelRate > hwconfig->lcd_configs[current_lcd].max_pixelrate)
return 1;
/* Check required REGM, REGN values */
clock_divider div = calculate_dss_clock_divider(params->PixelRate);
if((div.regm > REG_MAX(DSI_PLL_CONFIGURATION1_DSI_PLL_REGM)) || (div.regn > REG_MAX(DSI_PLL_CONFIGURATION1_DSI_PLL_REGN)))
return 1;
/* calculate_dss_clock_divider should make sure Fint is valid, so no need to check that */
/* Now check mode timings */
if((params->HorizSyncWidth > hwconfig->max_sync)
|| (params->HorizBackPorch > hwconfig->max_porch)
|| (params->HorizFrontPorch > hwconfig->max_porch)
|| (params->VertiSyncWidth > hwconfig->max_sync)
|| (params->VertiBackPorch > hwconfig->max_porch)
|| (params->VertiFrontPorch > hwconfig->max_porch))
return 1;
/* Check (HBP+HSW+HFP)*PCD > 8 */
if(params->HorizBackPorch+params->HorizSyncWidth+params->HorizFrontPorch <= 4) /* We always used PCD of 2 */
return 1;
}
/* Check screen size */
if((params->HorizDisplaySize-1 > REG_MAX(DISPC_SIZE_LCD_PPL))
|| (params->VertiDisplaySize-1 > REG_MAX(DISPC_SIZE_LCD_LPP))
|| (params->HorizDisplaySize & 0x7)) /* Width must be multiple of 8 pixels for STALLMODE=0 */
return 1;
/* Check colour depth */
switch(params->PixelDepth)
{
case VIDCLIST3_1BPP:
case VIDCLIST3_2BPP:
case VIDCLIST3_4BPP:
case VIDCLIST3_8BPP:
case VIDCLIST3_16BPP: /* TODO - Should be removed at some point! */
case VIDCLIST3_32BPP:
break;
default:
return 1;
}
/* Else we're good */
r->r[0] = 0;
return 0;
}
static int do_displayfeatures(_kernel_swi_regs *r)
{
r->r[0] = 0x6; /* Hardware pointer, interlace with progressive framestore */
if(overlay_desktop == OVERLAY_GFX)
r->r[1] = 0x3f; /* 1, 2, 4, 8, 16, 32bpp */
else
r->r[1] = 0x30; /* Only 16bpp, 32bpp */
r->r[2] = 32; /* 32 byte buffer alignment? */
r->r[4] = 0;
return 0;
}
static int do_framestoreaddress(_kernel_swi_regs *r)
{
/* Nothing */
return 1;
}
static int do_writepaletteentry(_kernel_swi_regs *r)
{
/* TODO - Handle lack of CPR on TV-out */
r->r[4] = 0;
u32 idx = r->r[2];
switch(r->r[0])
{
case 0:
if(idx < 256)
gfx_palette_l[idx] = ((u32) r->r[1]) >> 8;
break;
case 1:
if(!idx)
dispc->default_color[0] = dispc->default_color[1] = ((u32) r->r[1]) >> 8;
break;
case 2:
if(idx < 4)
{
mouse_palette_soft[idx] = ((u32) r->r[1]) >> 8;
mouse_dirty = true;
}
break;
}
return 0;
}
static int do_writepaletteentries(_kernel_swi_regs *r)
{
/* TODO - Handle lack of CPR on TV-out */
r->r[4] = 0;
u32 idx = r->r[2];
u32 c = r->r[3];
u32 *pal = (u32 *) r->r[1];
switch(r->r[0])
{
case 0:
while(c-- && (idx < 256))
gfx_palette_l[idx++] = (*pal++) >> 8;
break;
case 1:
if(!idx && c)
dispc->default_color[0] = dispc->default_color[1] = (*pal) >> 8;
break;
case 2:
while(c-- && (idx < 4))
mouse_palette_soft[idx++] = (*pal++) >> 8;
mouse_dirty = true;
break;
}
return 0;
}
static int do_readpaletteentry(_kernel_swi_regs *r)
{
r->r[4] = 0;
return 0;
}
static int do_render(_kernel_swi_regs *r)
{
overlay *o = &overlays[overlay_desktop];
if(!sdmachan || (o->target == TARGET_NONE)) /* Protect against (unlikely) event of lack of acceleration, or (likely) event of us not knowing the framebuffer setup yet */
return 1;
switch(r->r[1])
{
case GVRender_NOP:
goto complete;
case GVRender_CopyRectangle:
if(!sdma_copyrect(o,(copyrect_params *)r->r[2]))
break;
goto complete;
case GVRender_FillRectangle:
if(!sdma_fillrect(o,(fillrect_params *)r->r[2]))
break;
goto complete;
}
if(r->r[0] & GVRender_SyncIfNotComplete)
sdma_sync();
return 1;
complete:
if(r->r[0] & GVRender_SyncIfComplete)
sdma_sync();
r->r[4] = 0;
return 0;
}
static int do_iicop(_kernel_swi_regs *r)
{
/* TODO! */
return 0;
}
static int do_selecthead(_kernel_swi_regs *r)
{
/* TODO? */
return 0;
}
int graphicsv_handler(_kernel_swi_regs *r,void *pw)
{
if((((u32)r->r[4])>>24) != graphicsv_driver_number)
return 1;
uint16_t func = (uint16_t) r->r[4];
switch(func)
{
case GraphicsV_Complete: return do_null(r);
case GraphicsV_VSync: return do_vsync(r);
case GraphicsV_SetMode: return do_setmode(r);
case GraphicsV_SetInterlace: return do_setinterlace(r);
case GraphicsV_SetBlank: return do_setblank(r);
case GraphicsV_UpdatePointer: return do_updatepointer(r);
case GraphicsV_SetDMAAddress: return do_setdmaaddress(r);
case GraphicsV_VetMode: return do_vetmode(r);
case GraphicsV_DisplayFeatures: return do_displayfeatures(r);
case GraphicsV_FramestoreAddress: return do_framestoreaddress(r);
case GraphicsV_WritePaletteEntry: return do_writepaletteentry(r);
case GraphicsV_WritePaletteEntries: return do_writepaletteentries(r);
case GraphicsV_ReadPaletteEntry: return do_readpaletteentry(r);
case GraphicsV_Render: return do_render(r);
case GraphicsV_IICOp: return do_iicop(r);
case GraphicsV_SelectHead: return do_selecthead(r);
default: return 1;
}
}
/*
 * Copyright (c) 2010, RISC OS Open Ltd
 * All rights reserved.
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "Global/RISCOS.h"
#include "Global/HALEntries.h"
#include "swis.h"
#include "DebugLib/DebugLib.h"
#include "regs.h"
#include "videodevice.h"
volatile dss_regs *dss;
volatile dispc_regs *dispc;
volatile rfbi_regs *rfbi;
volatile venc_regs *venc;
volatile dsi_regs *dsi;
volatile dsi_phy_regs *dsi_phy;
volatile dsi_pll_regs *dsi_pll;
volatile sdma_regs *sdma;
volatile sdmachan_regs *sdmachan;
u32 ban_hardware_update = BHUB_OFF;
#ifdef DEBUGLIB
static int failedupdates=0;
#endif
/* Atomic update of ban flags */
void set_ban(u32 flags)
{
int irqs = _kernel_irqs_disabled();
if(!irqs)
_kernel_irqs_off();
ban_hardware_update |= flags;
if(!irqs)
_kernel_irqs_on();
}
void clear_ban(u32 flags)
{
int irqs = _kernel_irqs_disabled();
if(!irqs)
_kernel_irqs_off();
ban_hardware_update &= ~flags;
#ifdef DEBUGLIB
if(!ban_hardware_update && failedupdates)
dprintf(("","clear_ban: %d updates failed due to ban\n",failedupdates));
failedupdates = 0;
#endif
if(!irqs)
_kernel_irqs_on();
}
bool begin_quick_hardware_update(int *irqstate)
{
*irqstate = _kernel_irqs_disabled();
if(!*irqstate)
_kernel_irqs_off();
if(ban_hardware_update)
{
#ifdef DEBUGLIB
failedupdates++;
#endif
if(!*irqstate)
_kernel_irqs_on();
return false;
}
return true;
}
void end_quick_hardware_update(int irqstate)
{
if(!irqstate)
_kernel_irqs_on();
}
bool begin_slow_hardware_update(int *irqstate)
{
int irqs = _kernel_irqs_disabled();
if(!irqs)
_kernel_irqs_off();
if(ban_hardware_update)
{
#ifdef DEBUGLIB
failedupdates++;
#endif
if(!irqs)
_kernel_irqs_on();
return false;
}
/* Else we're free to update; disable video IRQ and re-enable global IRQs */
/* This is a bit naughty, really we should properly handle the case where it's a shared IRQ */
_kernel_oserror *e = _swix(OS_Hardware, _IN(0) | _INR(8,9) | _OUT(0), dev->dev.devicenumber&~(1u<<31), 0, EntryNo_HAL_IRQDisable, irqstate);
#ifdef DEBUGLIB
if(e)
failedupdates++;
#endif
if(!irqs)
_kernel_irqs_on();
#ifdef DEBUGLIB
else
dprintf(("","begin_slow_hardware_update: Warning, IRQs disabled!\n")); /* Warn if IRQs were disabled all entry - slow updates could be too slow to allow IRQs to be off globally */
#endif
return (e?false:true);
}
void end_slow_hardware_update(int irqstate)
{
if(irqstate)
_swix (OS_Hardware, _IN(0) | _INR(8,9), dev->dev.devicenumber&~(1u<<31), 0, EntryNo_HAL_IRQEnable);
}
/*
*Copyright(c)2010, RISC OS Open Ltd
*Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "sdma.h"
#include "DebugLib/DebugLib.h"
#ifdef DEBUGLIB
int sdma_stats[4];
#endif
void sdma_sync(void)
{
while(sdmachan->ccr & (DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE)) {}; /* TODO - Timeout/error checking */
}
bool sdma_copyrect(overlay *o,copyrect_params *r)
{
#ifdef DEBUGLIB
if((r->src_left >= o->width) || (r->src_bottom >= o->height) || (r->src_left + r->width + 1 > o->width) || (r->src_bottom + r->height + 1 > o->height) || (r->dest_left >= o->width) || (r->dest_bottom >= o->height) || (r->dest_left + r->width + 1 > o->width) || (r->dest_bottom + r->height + 1 > o->height))
dprintf(("","Bad copy rect? src %d,%d dest %d,%d size %d,%d overlay %d,%d\n",r->src_left,r->src_bottom,r->dest_left,r->dest_bottom,r->width+1,r->height+1,o->width,o->height));
#endif
/* Calculate line length & start pos, in bits */
u8 bpp = overlay_format_bpp[o->format>>OVERLAY_ATTRIBUTES_FORMAT_SHIFT];
u32 src_x = r->src_left*bpp;
u32 dest_x = r->dest_left*bpp;
u32 width = (r->width+1)*bpp;
/* Calculate element size from alignment */
u32 csdp;
u32 temp = src_x | dest_x | width;
if(temp & 7)
return false; /* Not byte aligned; abort */
if(temp & 8)
csdp = DMA4_CSDP_DATA_TYPE_8;
else if(temp & 16)
csdp = DMA4_CSDP_DATA_TYPE_16;
else
csdp = DMA4_CSDP_DATA_TYPE_32;
/* Convert to bytes */
src_x = src_x >> 3;
dest_x = dest_x >> 3;
width = width >> 3;
/* Calculate start/end addresses */
u32 src_y = o->ba + o->stride*((o->height-r->src_bottom)-(r->height+1));
u32 dest_y = o->ba + o->stride*((o->height-r->dest_bottom)-(r->height+1));
src_y += src_x;
dest_y += dest_x;
/* Make sure previous is complete */
sdma_sync();
/* Start programming registers */
sdmachan->cen = width >> csdp; /* Relies on assumption about CSDP location & values! */
sdmachan->cfn = r->height+1;
if(dest_y <= src_y)
{
/* Copy in forwards direction, top to bottom */
sdmachan->cssa = src_y;
sdmachan->cdsa = dest_y;
sdmachan->csei = sdmachan->cdei = 1;
sdmachan->csfi = sdmachan->cdfi = (o->stride-width)+1;
#ifdef DEBUGLIB
sdma_stats[1]++;
#endif
}
else if(src_y+width <= dest_y)
{
/* Copy in forwards direction, bottom to top */
sdmachan->cssa = src_y + o->stride*r->height;
sdmachan->cdsa = dest_y + o->stride*r->height;
sdmachan->csei = sdmachan->cdei = 1;
sdmachan->csfi = sdmachan->cdfi = -width-o->stride+1;
#ifdef DEBUGLIB
sdma_stats[2]++;
#endif
}
else
{
/* Copy in backwards direction - this will be slow due to lack of burst transfers */
/* Splitting into multiple vertical strips might help, but for that we'd really need a nicer way of chaining channels other than stalling for completion of each strip */
sdmachan->cssa = src_y + width-(1<<csdp);
sdmachan->cdsa = dest_y + width-(1<<csdp);
sdmachan->csei = sdmachan->cdei = 1-(2<<csdp);
sdmachan->csfi = sdmachan->cdfi = o->stride+width+1-(2<<csdp);
#ifdef DEBUGLIB
sdma_stats[3]++;
#endif
}
sdmachan->csdp = csdp | DMA4_CSDP_SRC_PACKED | DMA4_CSDP_SRC_BURST_EN_64BYTES | DMA4_CSDP_DST_PACKED | DMA4_CSDP_DST_BURST_EN_64BYTES | DMA4_CSDP_WRITE_MODE_LAST_NONPOSTED;
sdmachan->ccr = DMA4_CCR_ENABLE | DMA4_CCR_SRC_AMODE_DOUBLEINDEX | DMA4_CCR_DST_AMODE_DOUBLEINDEX | DMA4_CCR_PREFETCH;
return true;
}
bool sdma_fillrect(overlay *o,fillrect_params *r)
{
u32 *oraeor = r->oraeor;
#ifdef DEBUGLIB
if((r->left >= o->width) || (r->top >= o->height) || (r->right >= o->width) || (r->bottom >= o->height) || (r->left > r->right) || (r->bottom > r->top))
dprintf(("","Bad fill rect? %d,%d -> %d,%d overlay %d,%d\n",r->left,r->top,r->right,r->bottom,o->width,o->height));
if(((u32)oraeor) & 63)
dprintf(("","Hmm, oraeor isn't 64 byte aligned\n"));
#endif
u32 col = oraeor[1];
int row;
/* Verify that it's a solid fill
We could handle *some* non-solid fills (e.g. fill every other scanline or every other pixel), but it would be a bit of a hassle to check for that */
for(row=0;row<8;row++)
{
if((oraeor[0] != 0xFFFFFFFF) || (oraeor[1] != col))
return false;
oraeor += 2;
}
col = ~col;
/* Calculate line length & start pos, in bits */
u8 bpp = overlay_format_bpp[o->format>>OVERLAY_ATTRIBUTES_FORMAT_SHIFT];
u32 left = r->left*bpp;
u32 width = (1+r->right-r->left)*bpp;
/* Calculate element size from alignment */
u32 csdp;
u32 temp = left | width;
bool pattern_16bit = ((col ^ (col<<16)) < 65536); /* True if left halfword == right halfword */
bool pattern_8bit = pattern_16bit && ((col ^ (col<<8)) < 0x1000000); /* True if all bytes are identical */
if(temp & 7)
return false; /* Not byte aligned; abort */
if(temp & 8)
{
if(!pattern_8bit) /* Byte alignment but not byte-size pattern */
return false;
csdp = DMA4_CSDP_DATA_TYPE_8;
}
else if((temp & 16) || ((col & 0xFF000000) && (bpp != 32))) /* COLOR is a 24bit register, with the top byte treated as zero when performing a 32bit constant fill. So only allow promotion to 32bit data type if top byte is zero. However we do allow nonzero top byte in 32bpp modes, under the assumption that it doesn't matter if the byte gets trashed. */
{
if(!pattern_16bit) /* Halfword alignment but not halfword-size pattern */
return false;
csdp = DMA4_CSDP_DATA_TYPE_16;
}
else
csdp = DMA4_CSDP_DATA_TYPE_32;
/* Make sure previous is complete */
sdma_sync();
/* Start programming registers */
sdmachan->color = col;
sdmachan->cen = width>>(3+csdp);
sdmachan->cfn = (r->top-r->bottom)+1;
sdmachan->cdsa = (left>>3)+o->ba+o->stride*(o->height-1-r->top);
sdmachan->cdei = 1;
sdmachan->cdfi = (o->stride-(width>>3))+1;
sdmachan->csdp = csdp | DMA4_CSDP_SRC_PACKED | DMA4_CSDP_SRC_BURST_EN_64BYTES | DMA4_CSDP_DST_PACKED | DMA4_CSDP_DST_BURST_EN_64BYTES | DMA4_CSDP_WRITE_MODE_LAST_NONPOSTED;
sdmachan->ccr = DMA4_CCR_ENABLE | DMA4_CCR_DST_AMODE_DOUBLEINDEX | DMA4_CCR_CONST_FILL_ENABLE;
#ifdef DEBUGLIB
sdma_stats[0]++;
#endif
return true;
}
/*
*Copyright(c)2010, RISC OS Open Ltd
*Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 <stddef.h>
#include "Global/RISCOS.h"
#include "Global/HALEntries.h"
#include "swis.h"
#include "venc.h"
#include "regs.h"
#include "globals.h"
#include "dispc.h"
#include "DebugLib/DebugLib.h"
static const venc_regs template_ntsc_601 = {
0x00000000, // _pad
0x00000000, // status
0x00000000, // f_control
0x00000000, // _pad2
0x00000001, // vidout_ctrl
0x00008040, // sync_ctrl
0x00000000, // _pad3
0x00000359, // llen
0x0000020c, // flens
0x00000000, // hfltr_ctrl
0x043f2631, // cc_carr_wss_carr
0x00000000, // c_phase
0x00000102, // gain_u
0x0000016c, // gain_v
0x0000012f, // gain_y
0x00000043, // black_level
0x00000038, // blank_level
0x00000007, // x_color
0x00000001, // m_control
0x00000038, // bstamp_wss_data
0x21f07c1f, // s_carr
0x00000000, // line21
0x01310011, // ln_sel
0x0000f003, // l21_wc_ctl
0x00000000, // htrigger_vtrigger
0x069300f4, // savid_eavid
0x0016020c, // flen_fal
0x00060107, // lal_phase_reset
0x008e0350, // hs_int_start_stop_x
0x000f0359, // hs_ext_start_stop_x
0x01a00000, // vs_int_start_x
0x020701a0, // vs_int_stop_x_vs_int_start_y
0x01ac0024, // vs_int_stop_y_vs_ext_start_x
0x020d01ac, // vs_ext_stop_x_vs_ext_start_y
0x00000006, // vs_ext_stop_y
0x00000000, // _pad4
0x03480078, // avid_start_stop_x
0x02060024, // avid_start_stop_y
0x00000000, // _pad5
0x00000000, // _pad6
0x0001008a, // fid_int_start_x_fid_int_start_y
0x01ac0106, // fid_int_offset_y_fid_ext_start_x
0x01060006, // fid_ext_start_y_fid_ext_offset_y
0x00000000, // _pad7
0x00140001, // tvdetgp_int_start_stop_x
0x00010001, // tvdetgp_int_start_stop_y
0x00f90000, // gen_ctrl
0x00000000, // _pad8
0x00000000, // _pad9
0x00000000, // output_control
0x00000000, // output_test
};
static const venc_regs template_pal_601 = {
0x00000000, // _pad
0x00000000, // status
0x00000000, // f_control
0x00000000, // _pad2
0x00000001, // vidout_ctrl
0x00000040, // sync_ctrl
0x00000000, // _pad3
0x0000035f, // llen
0x00000270, // flens
0x00000000, // hfltr_ctrl
0x2f7225ed, // cc_carr_wss_carr
0x00000000, // c_phase
0x00000111, // gain_u
0x00000181, // gain_v
0x00000140, // gain_y
0x0000003b, // black_level
0x0000003b, // blank_level
0x00000007, // x_color
0x00000002, // m_control
0x0000003f, // bstamp_wss_data
0x2a098acb, // s_carr
0x00000000, // line21
0x01290015, // ln_sel
0x0000f603, // l21_wc_ctl
0x00000000, // htrigger_vtrigger
0x06a70108, // savid_eavid
0x00180270, // flen_fal
0x00040135, // lal_phase_reset
0x00880358, // hs_int_start_stop_x
0x000f035f, // hs_ext_start_stop_x
0x01a70000, // vs_int_start_x
0x000001a7, // vs_int_stop_x_vs_int_start_y
0x01af0000, // vs_int_stop_y_vs_ext_start_x
0x000101af, // vs_ext_stop_x_vs_ext_start_y
0x00000025, // vs_ext_stop_y
0x00000000, // _pad4
0x03530083, // avid_start_stop_x
0x026c002e, // avid_start_stop_y
0x00000000, // _pad5
0x00000000, // _pad6
0x0001008a, // fid_int_start_x_fid_int_start_y
0x002e0138, // fid_int_offset_y_fid_ext_start_x
0x01380001, // fid_ext_start_y_fid_ext_offset_y
0x00000000, // _pad7
0x00140001, // tvdetgp_int_start_stop_x
0x00010001, // tvdetgp_int_start_stop_y
0x00ff0000, // gen_ctrl
0x00000000, // _pad8
0x00000000, // _pad9
0x00000000, // output_control
0x00000000, // output_test
};
static const venc_regs *venc_templates[TVMODE_MAX] = {
&template_ntsc_601, /* As per TRM */
&template_pal_601, /* As per TRM. Broken? */
};
void venc_set_tvmode(tvmode mode,tvouttype type,bool showtestcard)
{
/* Avoid pointless updates */
if((mode == current_tvmode) && (type == current_tvtype) && (showtestcard == testcard))
{
/* But at the least we do want to update the overlays */
if(type != TVOUT_NONE)
{
int irqs;
if(!begin_quick_hardware_update(&irqs))
{
/* TODO - Mark as pending! */
return;
}
/* Flush any pending overlay updates */
for(int i=0;i<OVERLAY_MAX;i++)
dispc_update_overlay((overlayidx)i);
/* Update transparency settings*/
dispc_flush_transparency_cfg(true);
end_quick_hardware_update(irqs);
}
return;
}
dprintf(("","venc_set_tvmode: Mode %d type %d testcard %d\n",mode,type,showtestcard));
current_tvmode = mode;
current_tvtype = type;
testcard = showtestcard;
if(type == TVOUT_NONE)
{
/* Disable */
int irqs;
if(!begin_quick_hardware_update(&irqs))
{
/* TODO - Mark as pending! */
return;
}
/* TODO - check that this is the correct shutdown sequence */
dispc->control &= ~DISPC_CONTROL_DIGITALENABLE;
end_quick_hardware_update(irqs);
return;
}
/* Enable, as per flow in spruf98d 15.5.8.3 (p2336) */
int irqs;
if(!begin_slow_hardware_update(&irqs))
{
/* TODO - Mark as pending! */
return;
}
/* 1. Initialise the video encoder and the display controller configuration registers */
/* TODO - Need to set DISPC_CONTROL_HT, DISPC_DIVISOR? */
/* 0. Disable digital output! */
/* TODO - Do any other stuff to disable it properly */
dispc->control &= ~DISPC_CONTROL_DIGITALENABLE;
/* 1. Soft reset */
venc->f_control = VENC_F_CONTROL_RESET;
int timeout=1000000;
while((venc->f_control & VENC_F_CONTROL_RESET) && --timeout) {};
if(!timeout)
{
dprintf(("","venc_set_tvmode: Timeout waiting for VENC_F_CONTROL_RESET clear\n"));
}
/* 2. Save IRQ state */
u32 irqenable = dispc->irqenable;
dispc->irqenable = 0;
/* 15.5.8.2 SVideo/Composite selection in DSS_CONTROL */
if(type == TVOUT_COMPOSITE)
dss->control &= ~DSS_CONTROL_VENC_OUT_SEL;
else
dss->control |= DSS_CONTROL_VENC_OUT_SEL;
/* 3. Program registers as per table 15-69 */
const venc_regs *template = venc_templates[mode];
const u32 *temp = (const u32 *) template;
u32 *dest = (u32 *) venc;
for(u32 offset=0;offset<sizeof(venc_regs);offset+=4)
{
/* Skip padding, status register, VENC_F_CONTROL, VENC_SYNC_CTRL, VENC_OUTPUT_CONTROL */
if((offset != offsetof(venc_regs,_pad))
&& (offset != offsetof(venc_regs,_pad2))
&& (offset != offsetof(venc_regs,_pad3))
&& (offset != offsetof(venc_regs,_pad4))
&& (offset != offsetof(venc_regs,_pad5))
&& (offset != offsetof(venc_regs,_pad6))
&& (offset != offsetof(venc_regs,_pad7))
&& (offset != offsetof(venc_regs,_pad8))
&& (offset != offsetof(venc_regs,_pad9))
&& (offset != offsetof(venc_regs,status))
&& (offset != offsetof(venc_regs,f_control))
&& (offset != offsetof(venc_regs,sync_ctrl))
&& (offset != offsetof(venc_regs,output_control)))
{
dest[offset>>2] = temp[offset>>2];
}
}
/* Program VENC_OUTPUT_CONTROL with correct value for SVideo/composite */
if(type == TVOUT_COMPOSITE)
venc->output_control = 0xA;
else
venc->output_control = 0xD;
/* Program VENC_F_CONTROL and VENC_SYNC_CTRL last */
venc->f_control = (template->f_control&~VENC_F_CONTROL_SVDS_MASK) | (showtestcard?VENC_F_CONTROL_SVDS_TESTCARD:VENC_F_CONTROL_SVDS_EXTERNAL);
venc->sync_ctrl = template->sync_ctrl;
/* Program DISPC_SIZE_DIG appropriately */
/* TODO - Check that this code is correct for all modes and not just my two test modes! */
int w = (REG_EXTRACT(template->avid_start_stop_x,VENC_AVID_START_STOP_X_AVID_STOP_X)-REG_EXTRACT(template->avid_start_stop_x,VENC_AVID_START_STOP_X_AVID_START_X))-1;
int h = (REG_EXTRACT(template->flen_fal,VENC_FLEN_FAL_FLEN)/2)-REG_EXTRACT(template->flen_fal,VENC_FLEN_FAL_FAL);
dispc->size_dig = (w<<DISPC_SIZE_DIG_PPL_SHIFT) | (h<<DISPC_SIZE_DIG_LPP_SHIFT);
// if(mode == TVMODE_NTSC_601)
// dispc->size_dig = 0x00F002CF;
// else
// dispc->size_dig = 0x012002CF;
/* Flush any pending overlay updates */
for(int i=0;i<OVERLAY_MAX;i++)
dispc_update_overlay((overlayidx)i);
/* Update transparency settings*/
dispc_flush_transparency_cfg(false);
/* 4. Set the DISPC_CONTROL[6] GODIGITAL bit and DISPC_CONTROL[1] DIGITALENABLE bit to 1 */
/* Also, make sure EVSYNC_EVEN/EVSYNC_ODD are clear */
dispc->irqstatus = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
dispc->control |= DISPC_CONTROL_GODIGITAL | DISPC_CONTROL_DIGITALENABLE;
/* EXPERIMENTATION - Failed first time round, so let's wait a bit */
_swix(OS_Hardware,_IN(0)|_INR(8,9),100000,0,EntryNo_HAL_CounterDelay);
/* 5. Wait for the first VSYNC pulse signal */
timeout=10000000;
while(!(dispc->irqstatus & (DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD)) && --timeout) {};
if(!timeout)
{
dprintf(("","venc_set_tvmode: Timeout waiting for EVSYNC\n"));
}
/* 6. Clear the SYNCLOSTDIGITAL interrupt */
dispc->irqstatus = DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_SYNCLOSTDIGITAL;
/* 7. Enable the SYNCLOSTDIGITAL interrupt & restore earlier context */
/* Except if we're in test card mode - SYNCLOSTDIGITAL seems to occur all the time and should be ignored! */
irqenable |= DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD;
if(showtestcard)
irqenable &= ~DISPC_IRQ_SYNCLOSTDIGITAL;
else
irqenable |= DISPC_IRQ_SYNCLOSTDIGITAL;
dispc->irqenable = irqenable;
end_slow_hardware_update(irqs);
dprintf(("","venc_set_tvmode: Done\n"));
}
; Copyright (c) 2010, RISC OS Open Ltd
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * 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.
; * Neither the name of RISC OS Open Ltd nor the names of its contributors
; may be used to endorse or promote products derived from this software
; without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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 "Global/RISCOS.h"
#include "Global/Services.h"
#include "../VersionNum"
initialisation-code: module_init
finalisation-code: module_final
title-string: COMPONENT
help-string: COMPONENT Module_MajorVersion_CMHG
date-string: Module_Date_CMHG
#ifdef DEBUGLIB
command-keyword-table: module_commands
VideoRegs( min-args:0, max-args:0,
help-text: "*VideoRegs reads the registers from the video controller\n",
add-syntax:, invalid-syntax: "Syntax: *VideoRegs"),
TVMode( min-args:3, max-args:3,
help-text: "*TVMode calls venc_set_tvmode\n",
add-syntax:, invalid-syntax: "Syntax: *TVMode <mode> <type> <testcard>\n"),
TVRegs( min-args:0, max-args:0,
help-text: "*TVRegs reads the VENC registers\n",
add-syntax:, invalid-syntax: "Syntax: *TVRegs"),
TVOut( min-args:1, max-args:1,
help-text: "*TVOut switches RISC OS from LCD to TV out and vice-versa\n",
add-syntax:, invalid-syntax: "Syntax: *TVOut <mode>\n"),
SDMARegs( min-args:0, max-args:0,
help-text: "*SDMARegs reads the SDMA registers\n",
add-syntax:, invalid-syntax: "Syntax: *SDMARegs")
#endif
vector-handlers: dispc_irq_entry/dispc_irq_handler,
graphicsv_entry/graphicsv_handler
/*
 * Copyright (c) 2010, RISC OS Open Ltd
 * All rights reserved.
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */
#ifndef OMAPVIDEO_DISPC_H
#define OMAPVIDEO_DISPC_H
#include "kernel.h"
#include "regs.h"
#include "globals.h"
extern void dispc_update_overlay(overlayidx idx);
extern void dispc_set_lcdmode(lcdtimings *timings);
extern void dispc_flush_transparency_cfg(bool go);
extern int dispc_irq_handler(_kernel_swi_regs *r, void *pw);
#endif
/*
 * Copyright (c) 2010, RISC OS Open Ltd
 * All rights reserved.
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */
#ifndef OMAPVIDEO_DSI_H
#define OMAPVIDEO_DSI_H
#include "regs.h"
extern void dsi_pll_program_for_dispc(u32 pixel_rate);
#endif
/*
 * Copyright (c) 2010, RISC OS Open Ltd
 * All rights reserved.
 *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
 */
#ifndef OMAPVIDEO_DSS_H
#define OMAPVIDEO_DSS_H
#include "kernel.h"
#include "regs.h"
extern _kernel_oserror *dss_reset(void);
typedef struct {
u32 regm;
u32 regn;
} clock_divider;
extern clock_divider calculate_dss_clock_divider(u32 pixel_rate);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment