blob: e9c5d37994cdf1e1ecd774b55f9e1e674a460de9 [file] [log] [blame]
Googler25e92cf2023-12-13 10:05:01 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6/* System Headers */
7#include <common.h>
8#include <asm/arch/io.h>
9#include <asm/arch/secure_apb.h>
10
11
12/* Amlogic Headers */
13#include <amlogic/canvas.h>
14
15#define CANVAS_DEBUG_ENABLE
16#ifdef CANVAS_DEBUG_ENABLE
17#define canvas_log(fmt, args...) \
18 do { \
19 printf("[CANVAS]"fmt"\n", ##args); \
20 } while (0)
21#else
22#define canvas_log(fmt, args...)
23#endif
24
25#ifndef DMC_REG_BASE
26#define DMC_REG_BASE (0xFF638000L)
27#endif
28#define REG_CANVAS_ADDR(reg) (reg + 0L)
29
30#define CANVAS_NUM 256
31static canvas_t canvasPool[CANVAS_NUM];
32static int canvas_inited = 0;
33
34static inline u32 canvas_reg_read(u32 reg)
35{
36 u32 val;
37
38 if (reg > 0x10000)
39 val = *(volatile unsigned int *)REG_CANVAS_ADDR(reg);
40 else
41 val = readl(DMC_REG_BASE + reg);
42 return val;
43}
44
45static inline void canvas_reg_write(const u32 val, u32 reg)
46{
47 if (reg > 0x10000)
48 *(volatile unsigned int *)REG_CANVAS_ADDR(reg) = (val);
49 else
50 writel(val, (DMC_REG_BASE + reg));
51}
52
53void canvas_init(void)
54{
55 int index = 0;
56
57 if (canvas_inited == 1)
58 return;
59
60 canvas_log("canvas init");
61 canvas_reg_write(0, DC_CAV_LUT_DATAL);
62 canvas_reg_write(0, DC_CAV_LUT_DATAH);
63 for (index = 0; index < CANVAS_NUM; index++) {
64 canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
65 canvas_reg_read(DC_CAV_LUT_DATAH);
66 }
67
68 canvas_inited = 1;
69}
70
71void canvas_config(u32 index, ulong addr, u32 width,
72 u32 height, u32 wrap, u32 blkmode)
73{
74 canvas_t *canvasP = &canvasPool[index];
75
76 if (index >= CANVAS_NUM)
77 return;
78
79 canvas_init();
80
81 canvas_log("addr=0x%08lx width=%d, height=%d", addr, width, height);
82 canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
83 ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
84 DC_CAV_LUT_DATAL);
85 canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
86 CANVAS_WIDTH_HBIT) |
87 ((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
88 ((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
89 ((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
90 ((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
91 DC_CAV_LUT_DATAH);
92 canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
93 // read a cbus to make sure last write finish.
94 canvas_reg_read(DC_CAV_LUT_DATAH);
95
96 canvasP->addr = addr;
97 canvasP->width = width;
98 canvasP->height = height;
99 canvasP->wrap = wrap;
100 canvasP->blkmode = blkmode;
101
102}
103
104void canvas_read(u32 index, canvas_t *p)
105{
106 if (index < CANVAS_NUM)
107 *p = canvasPool[index];
108}
109
110void canvas_copy(u32 src, u32 dst)
111{
112 unsigned long addr;
113 unsigned width, height, wrap, blkmode;
114
115 if ((src >= CANVAS_NUM) || (dst >= CANVAS_NUM))
116 return;
117
118 addr = canvasPool[src].addr;
119 width = canvasPool[src].width;
120 height = canvasPool[src].height;
121 wrap = canvasPool[src].wrap;
122 blkmode = canvasPool[src].blkmode;
123
124 canvas_reg_write((((addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
125 ((((width + 7) >> 3) & CANVAS_WIDTH_LMASK) << CANVAS_WIDTH_LBIT),
126 DC_CAV_LUT_DATAL);
127 canvas_reg_write(((((width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
128 CANVAS_WIDTH_HBIT) |
129 ((height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
130 ((wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
131 ((wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
132 ((blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
133 DC_CAV_LUT_DATAH);
134 canvas_reg_write(CANVAS_LUT_WR_EN | dst, DC_CAV_LUT_ADDR);
135 // read a cbus to make sure last write finish.
136 canvas_reg_read(DC_CAV_LUT_DATAH);
137
138 canvasPool[dst].addr = addr;
139 canvasPool[dst].width = width;
140 canvasPool[dst].height = height;
141 canvasPool[dst].wrap = wrap;
142 canvasPool[dst].blkmode = blkmode;
143
144 return;
145}
146
147void canvas_update_addr(u32 index, u32 addr)
148{
149 if (index >= CANVAS_NUM)
150 return;
151
152 canvasPool[index].addr = addr;
153
154 canvas_reg_write((((canvasPool[index].addr + 7) >> 3) & CANVAS_ADDR_LMASK) |
155 ((((canvasPool[index].width + 7) >> 3) & CANVAS_WIDTH_LMASK) <<
156 CANVAS_WIDTH_LBIT), DC_CAV_LUT_DATAL);
157 canvas_reg_write(((((canvasPool[index].width + 7) >> 3) >> CANVAS_WIDTH_LWID) <<
158 CANVAS_WIDTH_HBIT) |
159 ((canvasPool[index].height & CANVAS_HEIGHT_MASK) << CANVAS_HEIGHT_BIT) |
160 ((canvasPool[index].wrap & CANVAS_XWRAP) ? CANVAS_XWRAP : 0) |
161 ((canvasPool[index].wrap & CANVAS_YWRAP) ? CANVAS_YWRAP : 0) |
162 ((canvasPool[index].blkmode & CANVAS_BLKMODE_MASK) << CANVAS_BLKMODE_BIT),
163 DC_CAV_LUT_DATAH);
164 canvas_reg_write(CANVAS_LUT_WR_EN | index, DC_CAV_LUT_ADDR);
165 // read a cbus to make sure last write finish.
166 canvas_reg_read(DC_CAV_LUT_DATAH);
167
168 return;
169}
170
171unsigned int canvas_get_addr(u32 index)
172{
173 return canvasPool[index].addr;
174}