15 #include <linux/export.h>
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/errno.h>
84 #define DI_GENERAL 0x0000
85 #define DI_BS_CLKGEN0 0x0004
86 #define DI_BS_CLKGEN1 0x0008
87 #define DI_SW_GEN0(gen) (0x000c + 4 * ((gen) - 1))
88 #define DI_SW_GEN1(gen) (0x0030 + 4 * ((gen) - 1))
89 #define DI_STP_REP(gen) (0x0148 + 4 * (((gen) - 1)/2))
90 #define DI_SYNC_AS_GEN 0x0054
91 #define DI_DW_GEN(gen) (0x0058 + 4 * (gen))
92 #define DI_DW_SET(gen, set) (0x0088 + 4 * ((gen) + 0xc * (set)))
93 #define DI_SER_CONF 0x015c
98 #define DI_SCR_CONF 0x0170
99 #define DI_STAT 0x0174
101 #define DI_SW_GEN0_RUN_COUNT(x) ((x) << 19)
102 #define DI_SW_GEN0_RUN_SRC(x) ((x) << 16)
103 #define DI_SW_GEN0_OFFSET_COUNT(x) ((x) << 3)
104 #define DI_SW_GEN0_OFFSET_SRC(x) ((x) << 0)
106 #define DI_SW_GEN1_CNT_POL_GEN_EN(x) ((x) << 29)
107 #define DI_SW_GEN1_CNT_CLR_SRC(x) ((x) << 25)
108 #define DI_SW_GEN1_CNT_POL_TRIGGER_SRC(x) ((x) << 12)
109 #define DI_SW_GEN1_CNT_POL_CLR_SRC(x) ((x) << 9)
110 #define DI_SW_GEN1_CNT_DOWN(x) ((x) << 16)
111 #define DI_SW_GEN1_CNT_UP(x) (x)
112 #define DI_SW_GEN1_AUTO_RELOAD (0x10000000)
114 #define DI_DW_GEN_ACCESS_SIZE_OFFSET 24
115 #define DI_DW_GEN_COMPONENT_SIZE_OFFSET 16
117 #define DI_GEN_POLARITY_1 (1 << 0)
118 #define DI_GEN_POLARITY_2 (1 << 1)
119 #define DI_GEN_POLARITY_3 (1 << 2)
120 #define DI_GEN_POLARITY_4 (1 << 3)
121 #define DI_GEN_POLARITY_5 (1 << 4)
122 #define DI_GEN_POLARITY_6 (1 << 5)
123 #define DI_GEN_POLARITY_7 (1 << 6)
124 #define DI_GEN_POLARITY_8 (1 << 7)
125 #define DI_GEN_POLARITY_DISP_CLK (1 << 17)
126 #define DI_GEN_DI_CLK_EXT (1 << 20)
127 #define DI_GEN_DI_VSYNC_EXT (1 << 21)
129 #define DI_POL_DRDY_DATA_POLARITY (1 << 7)
130 #define DI_POL_DRDY_POLARITY_15 (1 << 4)
132 #define DI_VSYNC_SEL_OFFSET 13
144 static int ipu_di_clk_calc_div(
unsigned long inrate,
unsigned long outrate)
167 if ((div & 0xC) == 0xC) {
176 static unsigned long clk_di_recalc_rate(
struct clk_hw *
hw,
177 unsigned long parent_rate)
180 unsigned long outrate;
186 outrate = (parent_rate /
div) * 16;
191 static long clk_di_round_rate(
struct clk_hw *hw,
unsigned long rate,
192 unsigned long *
prate)
195 unsigned long outrate;
199 div = ipu_di_clk_calc_div(*prate, rate);
201 outrate = (*prate /
div) * 16;
206 outrate = *prate / 2;
209 "%s: inrate: %ld div: 0x%08x outrate: %ld wanted: %ld\n",
210 __func__, *prate, div, outrate, rate);
215 static int clk_di_set_rate(
struct clk_hw *hw,
unsigned long rate,
216 unsigned long parent_rate)
224 div = ipu_di_clk_calc_div(parent_rate, rate);
228 dev_dbg(di->
ipu->dev,
"%s: inrate: %ld desired: %ld div: 0x%08x\n",
229 __func__, parent_rate, rate, div);
233 static u8 clk_di_get_parent(
struct clk_hw *hw)
243 static int clk_di_set_parent(
struct clk_hw *hw,
u8 index)
260 static struct clk_ops clk_di_ops = {
261 .round_rate = clk_di_round_rate,
262 .set_rate = clk_di_set_rate,
263 .recalc_rate = clk_di_recalc_rate,
264 .set_parent = clk_di_set_parent,
265 .get_parent = clk_di_get_parent,
268 static void ipu_di_data_wave_config(
struct ipu_di *di,
275 ipu_di_write(di, reg,
DI_DW_GEN(wave_gen));
278 static void ipu_di_data_pin_config(
struct ipu_di *di,
int wave_gen,
int di_pin,
279 int set,
int up,
int down)
283 reg = ipu_di_read(di,
DI_DW_GEN(wave_gen));
284 reg &= ~(0x3 << (di_pin * 2));
285 reg |=
set << (di_pin * 2);
286 ipu_di_write(di, reg,
DI_DW_GEN(wave_gen));
288 ipu_di_write(di, (down << 16) | up,
DI_DW_SET(wave_gen,
set));
297 for (i = 0; i <
count; i++) {
299 int wave_gen = start + i + 1;
305 dev_err(di->
ipu->dev,
"DI%d counters out of range.\n",
331 reg &= ~(0xffff << (16 * ((wave_gen - 1) & 0x1)));
332 reg |= c->
repeat_count << (16 * ((wave_gen - 1) & 0x1));
337 static void ipu_di_sync_config_interlaced(
struct ipu_di *di,
347 .run_count = h_total / 2 - 1,
350 .run_count = h_total - 11,
354 .run_count = v_total * 2 - 1,
360 .run_count = v_total / 2 - 1,
368 .repeat_count = sig->
height / 2,
371 .run_count = v_total - 1,
374 .run_count = v_total / 2 - 1,
384 .repeat_count = sig->
width,
387 .run_count = v_total - 1,
389 .offset_count = v_total / 2,
396 ipu_di_sync_config(di, cfg, 0,
ARRAY_SIZE(cfg));
401 reg |= (3 - 1) << 29 | 0x00008000;
407 static void ipu_di_sync_config_noninterlaced(
struct ipu_di *di,
419 .run_count = h_total - 1,
423 .cnt_polarity_gen_en = 1,
427 .run_count = v_total - 1,
429 .cnt_polarity_gen_en = 1,
436 .repeat_count = sig->
height,
442 .repeat_count = sig->
width,
456 ipu_di_sync_config(di, cfg, 0,
ARRAY_SIZE(cfg));
464 u32 h_total, v_total;
469 dev_dbg(di->
ipu->dev,
"disp %d: panel size = %d x %d\n",
483 "setting pixel clock to parent %s failed with %d\n",
509 ipu_di_data_wave_config(di,
SYNC_WAVE, div - 1, div - 1);
516 ipu_di_sync_config_interlaced(di, sig);
519 di_gen |= 0x10000000;
530 ipu_di_sync_config_noninterlaced(di, sig, div);
548 reg = ipu_di_read(di,
DI_POL);
556 ipu_di_write(di, reg,
DI_POL);
604 di = ERR_PTR(-
EBUSY);
633 struct clk_init_data init = {
650 return PTR_ERR(di->
clk_di);
664 init.parent_names = (
const char **)&di_parent;
677 goto failed_clk_register;
680 dev_info(dev,
"DI%d base: 0x%08lx remapped to %p\n",