blob: 11957dc69d74f5aaaa26bd38a6fb024e35162080 [file] [log] [blame]
/*
* AMLOGIC Canvas management driver.
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
/* System Headers */
#include <common.h>
#include <asm/arch/io.h>
#include <asm/arch/secure_apb.h>
/* Amlogic Headers */
#include <amlogic/canvas.h>
#ifdef BL33_DEBUG_PRINT
#define CANVAS_DEBUG_ENABLE
#endif
#ifdef CANVAS_DEBUG_ENABLE
#define canvas_log(fmt, args...) \
do { \
printf("[CANVAS]"fmt"\n", ##args); \
} while (0)
#else
#define canvas_log(fmt, args...)
#endif
#define canvas_reg_read(reg) readl(DMC_REG_BASE + reg)
#define canvas_reg_write(val, reg) writel(val, (DMC_REG_BASE + reg))
#define CANVAS_NUM 256
static canvas_t canvasPool[CANVAS_NUM];
static int canvas_inited = 0;
void canvas_init(void)
{
int index = 0;
if (canvas_inited == 1)
return;
canvas_log("canvas init");
canvas_reg_write(0, DC_CAV_LUT_DATAL);
canvas_reg_write(0, DC_CAV_LUT_DATAH);
for (index = 0; index < CANVAS_NUM; index++) {
canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
canvas_reg_read(DC_CAV_LUT_DATAH);
}
canvas_inited = 1;
}
void canvas_config(u32 index, ulong addr, u32 width,
u32 height, u32 wrap, u32 blkmode)
{
canvas_t *canvasP = &canvasPool[index];
if (index >= CANVAS_NUM)
return;
canvas_init();
canvas_log("addr=0x%08lx width=%d, height=%d", addr, width, height);
canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
DC_CAV_LUT_DATAL);
canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
CANVAS_WIDTH_HBIT) |
((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
DC_CAV_LUT_DATAH);
canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
// read a cbus to make sure last write finish.
canvas_reg_read(DC_CAV_LUT_DATAH);
canvasP->addr = addr;
canvasP->width = width;
canvasP->height = height;
canvasP->wrap = wrap;
canvasP->blkmode = blkmode;
}
void canvas_read(u32 index, canvas_t *p)
{
if (index < CANVAS_NUM)
*p = canvasPool[index];
}
void canvas_copy(u32 src, u32 dst)
{
unsigned long addr;
unsigned width, height, wrap, blkmode;
if ((src >= CANVAS_NUM) || (dst >= CANVAS_NUM))
return;
addr = canvasPool[src].addr;
width = canvasPool[src].width;
height = canvasPool[src].height;
wrap = canvasPool[src].wrap;
blkmode = canvasPool[src].blkmode;
canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
DC_CAV_LUT_DATAL);
canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
CANVAS_WIDTH_HBIT) |
((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
DC_CAV_LUT_DATAH);
canvas_reg_write(CANVAS_LUT_WR_EN | dst, DC_CAV_LUT_ADDR);
// read a cbus to make sure last write finish.
canvas_reg_read(DC_CAV_LUT_DATAH);
canvasPool[dst].addr = addr;
canvasPool[dst].width = width;
canvasPool[dst].height = height;
canvasPool[dst].wrap = wrap;
canvasPool[dst].blkmode = blkmode;
return;
}
void canvas_update_addr(u32 index, u32 addr)
{
if (index >= CANVAS_NUM)
return;
canvasPool[index].addr = addr;
canvas_reg_write((((canvasPool[index].addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
((((canvasPool[index].width + 7) >> 3) & CANVAS_WIDTH_LMASK) <<
CANVAS_WIDTH_LBIT), DC_CAV_LUT_DATAL);
canvas_reg_write(((((canvasPool[index].width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
CANVAS_WIDTH_HBIT) |
((canvasPool[index].height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
((canvasPool[index].wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
((canvasPool[index].wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
((canvasPool[index].blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
DC_CAV_LUT_DATAH);
canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
// read a cbus to make sure last write finish.
canvas_reg_read(DC_CAV_LUT_DATAH);
return;
}
unsigned int canvas_get_addr(u32 index)
{
return canvasPool[index].addr;
}