1 /*
2 * vendor/amlogic/media/common/ge2d/ge2d_io.h
3 *
4 * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18 #ifndef _GE2D_IO_H_
19 #define _GE2D_IO_H_
20
21 #include <linux/io.h>
22 #include <linux/amlogic/iomap.h>
23 #include <linux/amlogic/cpu_version.h>
24 #include <linux/amlogic/power_ctrl.h>
25 #include <linux/amlogic/power_domain.h>
26
27 #include "ge2d_log.h"
28
29 #define GE2DBUS_REG_ADDR(reg) ((((reg)-0x1800) << 2))
30 #define GE2D_PWR_DOMAIN 19
31
32 extern unsigned int ge2d_dump_reg_cnt;
33 extern unsigned int ge2d_dump_reg_enable;
34 extern void __iomem *ge2d_reg_map;
35
36 struct reg_map_s {
37 unsigned int phy_addr;
38 unsigned int size;
39 void __iomem *vir_addr;
40 int flag;
41 };
42
43 static struct reg_map_s reg_map = {
44 .phy_addr = 0xd0160000,
45 .size = 0x10000,
46 };
47
check_map_flag(unsigned int addr)48 static int check_map_flag(unsigned int addr)
49 {
50 int ret = 0;
51
52 if (reg_map.flag) {
53 return 1;
54 }
55
56 if (ge2d_reg_map) {
57 reg_map.vir_addr = ge2d_reg_map;
58 reg_map.flag = 1;
59 ret = 1;
60 } else {
61 reg_map.vir_addr = ioremap(reg_map.phy_addr, reg_map.size);
62 if (!reg_map.vir_addr) {
63 pr_info("failed map phy: 0x%x\n", addr);
64 ret = 0;
65 } else {
66 reg_map.flag = 1;
67 ge2d_log_dbg("mapped phy: 0x%x\n", reg_map.phy_addr);
68 ret = 1;
69 }
70 }
71 return ret;
72 }
73
ge2d_reg_read(unsigned int reg)74 static uint32_t ge2d_reg_read(unsigned int reg)
75 {
76 unsigned int addr = 0;
77 unsigned int val = 0;
78
79 if (get_cpu_type() < MESON_CPU_MAJOR_ID_GXBB) {
80 return (uint32_t)aml_read_cbus(reg);
81 }
82
83 addr = GE2DBUS_REG_ADDR(reg);
84 if (check_map_flag(addr)) {
85 val = readl(reg_map.vir_addr + addr);
86 }
87
88 ge2d_log_dbg2("read(0x%x)=0x%x\n", reg_map.phy_addr + addr, val);
89
90 return val;
91 }
92
ge2d_reg_write(unsigned int reg,unsigned int val)93 static void ge2d_reg_write(unsigned int reg, unsigned int val)
94 {
95 unsigned int addr = 0;
96
97 if (get_cpu_type() < MESON_CPU_MAJOR_ID_GXBB) {
98 aml_write_cbus(reg, val);
99 return;
100 }
101
102 addr = GE2DBUS_REG_ADDR(reg);
103 if (check_map_flag(addr)) {
104 writel(val, reg_map.vir_addr + addr);
105 }
106 if (ge2d_dump_reg_enable && (ge2d_dump_reg_cnt > 0)) {
107 ge2d_log_info("write(0x%x) = 0x%x\n", reg, val);
108 ge2d_dump_reg_cnt--;
109 }
110 }
111
ge2d_vcbus_read(uint32_t reg)112 static inline uint32_t ge2d_vcbus_read(uint32_t reg)
113 {
114 return (uint32_t)aml_read_vcbus(reg);
115 };
116
ge2d_reg_get_bits(uint32_t reg,const uint32_t start,const uint32_t len)117 static inline uint32_t ge2d_reg_get_bits(uint32_t reg, const uint32_t start, const uint32_t len)
118 {
119 uint32_t val;
120
121 val = (ge2d_reg_read(reg) >> (start)) & ((1L << (len)) - 1);
122 return val;
123 }
124
ge2d_reg_set_bits(uint32_t reg,const uint32_t value,const uint32_t start,const uint32_t len)125 static inline void ge2d_reg_set_bits(uint32_t reg, const uint32_t value, const uint32_t start, const uint32_t len)
126 {
127 ge2d_reg_write(
128 reg, ((ge2d_reg_read(reg) & ~(((1L << (len)) - 1) << (start))) | (((value) & ((1L << (len)) - 1)) << (start))));
129 }
130
ge2d_hiu_setb(unsigned int _reg,unsigned int _value,unsigned int _start,unsigned int _len)131 static void ge2d_hiu_setb(unsigned int _reg, unsigned int _value, unsigned int _start, unsigned int _len)
132 {
133 aml_write_hiubus(_reg, ((aml_read_hiubus(_reg) & ~(((1L << (_len)) - 1) << (_start))) |
134 (((_value) & ((1L << (_len)) - 1)) << (_start))));
135 }
136
ge2d_ao_setb(unsigned int _reg,unsigned int _value,unsigned int _start,unsigned int _len)137 static void ge2d_ao_setb(unsigned int _reg, unsigned int _value, unsigned int _start, unsigned int _len)
138 {
139 aml_write_aobus(_reg, ((aml_read_aobus(_reg) & ~(((1L << (_len)) - 1) << (_start))) |
140 (((_value) & ((1L << (_len)) - 1)) << (_start))));
141 }
142
ge2d_c_setb(unsigned int _reg,unsigned int _value,unsigned int _start,unsigned int _len)143 static void ge2d_c_setb(unsigned int _reg, unsigned int _value, unsigned int _start, unsigned int _len)
144 {
145 aml_write_cbus(_reg, ((aml_read_cbus(_reg) & ~(((1L << (_len)) - 1) << (_start))) |
146 (((_value) & ((1L << (_len)) - 1)) << (_start))));
147 }
148
ge2d_set_pwr_tbl_bits(unsigned int table_type,unsigned int reg,unsigned int val,unsigned int start,unsigned int len)149 static inline void ge2d_set_pwr_tbl_bits(unsigned int table_type, unsigned int reg, unsigned int val,
150 unsigned int start, unsigned int len)
151 {
152 switch (table_type) {
153 case CBUS_BASE:
154 ge2d_c_setb(reg, val, start, len);
155 break;
156 case AOBUS_BASE:
157 ge2d_ao_setb(reg, val, start, len);
158 break;
159 case HIUBUS_BASE:
160 ge2d_hiu_setb(reg, val, start, len);
161 break;
162 case GEN_PWR_SLEEP0:
163 power_ctrl_sleep(val ? 0 : 1, start);
164 break;
165 case GEN_PWR_ISO0:
166 power_ctrl_iso(val ? 0 : 1, start);
167 break;
168 case MEM_PD_REG0:
169 power_ctrl_mempd0(val ? 0 : 1, 0xFF, start);
170 break;
171 case PWR_DOMAIN_CTRL:
172 power_domain_switch(GE2D_PWR_DOMAIN, val);
173 break;
174 default:
175 ge2d_log_err("unsupported bus type\n");
176 break;
177 }
178 }
179 #endif
180