summaryrefslogtreecommitdiff
path: root/drivers/common/media_clock/clk/clkg12.c (plain)
blob: 9694959dd5ed3cd22f5cc00dc4edb451ce2d158a
1/*
2 * drivers/amlogic/media/common/arch/clk/clkgx.c
3 *
4 * Copyright (C) 2016 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#define DEBUG
18#include <linux/init.h>
19#include <linux/kernel.h>
20#include <linux/types.h>
21#include <linux/clk.h>
22#include <linux/delay.h>
23#include <linux/amlogic/media/clk/gp_pll.h>
24#include <linux/amlogic/media/utils/vdec_reg.h>
25#include <linux/amlogic/media/utils/amports_config.h>
26#include "../../../frame_provider/decoder/utils/vdec.h"
27#include <linux/amlogic/media/registers/register.h>
28#include "clk_priv.h"
29#include <linux/amlogic/media/utils/log.h>
30
31#include <linux/amlogic/media/registers/register_ops.h>
32#include "../switch/amports_gate.h"
33#include "../../chips/decoder_cpu_ver_info.h"
34
35#define MHz (1000000)
36#define debug_print pr_info
37#define TL1_HEVC_MAX_CLK (800)
38
39//#define NO_CLKTREE
40
41/* set gp0 648M vdec use gp0 clk*/
42#define VDEC1_648M() \
43 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (6 << 9) | (0), 0, 16)
44
45#define HEVC_648M() \
46 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, (6 << 9) | (0), 16, 16)
47
48/*set gp0 1296M vdec use gp0 clk div2*/
49#define VDEC1_648M_DIV() \
50 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (6 << 9) | (1), 0, 16)
51
52#define HEVC_648M_DIV() \
53 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, (6 << 9) | (1), 16, 16)
54
55#define VDEC1_WITH_GP_PLL() \
56 ((READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0xe00) == 0xc00)
57#define HEVC_WITH_GP_PLL() \
58 ((READ_HHI_REG(HHI_VDEC2_CLK_CNTL) & 0xe000000) == 0xc000000)
59
60#define VDEC1_CLOCK_ON() \
61 do { if (is_meson_m8_cpu()) { \
62 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 8, 1); \
63 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); \
64 } else { \
65 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 8, 1); \
66 WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 0, 15, 1); \
67 WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 0, 8, 1); \
68 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10); \
69 } \
70 } while (0)
71
72#define VDEC2_CLOCK_ON() do {\
73 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 1, 8, 1); \
74 WRITE_VREG(DOS_GCLK_EN1, 0x3ff);\
75 } while (0)
76
77#define HCODEC_CLOCK_ON() do {\
78 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 1, 24, 1); \
79 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);\
80 } while (0)
81#define HEVC_CLOCK_ON() do {\
82 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 1, 24, 1); \
83 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 1, 8, 1); \
84 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 0, 31, 1); \
85 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 0, 15, 1); \
86 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 0, 24, 1); \
87 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);\
88 } while (0)
89#define VDEC1_SAFE_CLOCK() do {\
90 WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, \
91 READ_HHI_REG(HHI_VDEC_CLK_CNTL) & 0x7f, 0, 7); \
92 WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 1, 8, 1); \
93 WRITE_HHI_REG_BITS(HHI_VDEC3_CLK_CNTL, 1, 15, 1);\
94 } while (0)
95
96#define VDEC1_CLOCK_OFF() \
97 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 0, 8, 1)
98#define VDEC2_CLOCK_OFF() \
99 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1)
100#define HCODEC_CLOCK_OFF() \
101 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, 0, 24, 1)
102#define HEVC_SAFE_CLOCK() do { \
103 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, \
104 (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) >> 16) & 0x7f, 16, 7);\
105 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, \
106 (READ_HHI_REG(HHI_VDEC2_CLK_CNTL) >> 25) & 0x7f, 25, 7);\
107 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 1, 24, 1); \
108 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 1, 31, 1);\
109 WRITE_HHI_REG_BITS(HHI_VDEC4_CLK_CNTL, 1, 15, 1);\
110 } while (0)
111
112#define HEVC_CLOCK_OFF() do {\
113 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 24, 1);\
114 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, 0, 8, 1);\
115}while(0)
116
117static int clock_real_clk[VDEC_MAX + 1];
118
119static unsigned int set_frq_enable, vdec_frq, hevc_frq, hevcb_frq;
120
121#ifdef NO_CLKTREE
122static struct gp_pll_user_handle_s *gp_pll_user_vdec, *gp_pll_user_hevc;
123static bool is_gp0_div2 = true;
124
125static int gp_pll_user_cb_vdec(struct gp_pll_user_handle_s *user,
126 int event)
127{
128 debug_print("gp_pll_user_cb_vdec call\n");
129 if (event == GP_PLL_USER_EVENT_GRANT) {
130 struct clk *clk = clk_get(NULL, "gp0_pll");
131 if (!IS_ERR(clk)) {
132 if (is_gp0_div2)
133 clk_set_rate(clk, 1296000000UL);
134 else
135 clk_set_rate(clk, 648000000UL);
136 VDEC1_SAFE_CLOCK();
137 VDEC1_CLOCK_OFF();
138 if (is_gp0_div2)
139 VDEC1_648M_DIV();
140 else
141 VDEC1_648M();
142
143 VDEC1_CLOCK_ON();
144 debug_print("gp_pll_user_cb_vdec call set\n");
145 }
146 }
147 return 0;
148}
149
150static int gp_pll_user_cb_hevc(struct gp_pll_user_handle_s *user,
151 int event)
152{
153 debug_print("gp_pll_user_cb_hevc callback\n");
154 if (event == GP_PLL_USER_EVENT_GRANT) {
155 struct clk *clk = clk_get(NULL, "gp0_pll");
156 if (!IS_ERR(clk)) {
157 if (is_gp0_div2)
158 clk_set_rate(clk, 1296000000UL);
159 else
160 clk_set_rate(clk, 648000000UL);
161// HEVC_SAFE_CLOCK();
162 HEVC_CLOCK_OFF();
163 if (is_gp0_div2)
164 HEVC_648M_DIV();
165 else
166 HEVC_648M();
167 HEVC_CLOCK_ON();
168 debug_print("gp_pll_user_cb_hevc callback2\n");
169 }
170 }
171
172 return 0;
173}
174
175
176#endif
177
178struct clk_mux_s {
179 struct gate_switch_node *vdec_mux_node;
180 struct gate_switch_node *hcodec_mux_node;
181 struct gate_switch_node *hevc_mux_node;
182 struct gate_switch_node *hevc_back_mux_node;
183};
184
185struct clk_mux_s gclk;
186
187void vdec1_set_clk(int source, int div)
188{
189 pr_debug("vdec1_set_clk %d, %d\n", source, div);
190 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL, (source << 9) | (div - 1), 0, 16);
191}
192EXPORT_SYMBOL(vdec1_set_clk);
193
194void hcodec_set_clk(int source, int div)
195{
196 WRITE_HHI_REG_BITS(HHI_VDEC_CLK_CNTL,
197 (source << 9) | (div - 1), 16, 16);
198}
199EXPORT_SYMBOL(hcodec_set_clk);
200
201void vdec2_set_clk(int source, int div)
202{
203 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL,
204 (source << 9) | (div - 1), 0, 16);
205}
206EXPORT_SYMBOL(vdec2_set_clk);
207
208//extern uint force_hevc_clock_cntl;
209uint force_hevc_clock_cntl = 0;
210void hevc_set_clk(int source, int div)
211{
212 if (force_hevc_clock_cntl) {
213 pr_info("%s, write force clock cntl %x\n", __func__, force_hevc_clock_cntl);
214 WRITE_HHI_REG(HHI_VDEC2_CLK_CNTL, force_hevc_clock_cntl);
215 } else {
216 pr_debug("hevc_set_clk %d, %d\n", source, div);
217 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL,
218 (source << 9) | (div - 1), 16, 16);
219 WRITE_HHI_REG_BITS(HHI_VDEC2_CLK_CNTL, (source << 9) | (div - 1), 0, 16);
220 }
221}
222EXPORT_SYMBOL(hevc_set_clk);
223
224void vdec_get_clk_source(int clk, int *source, int *div, int *rclk)
225{
226#define source_div4 (0)
227#define source_div3 (1)
228#define source_div5 (2)
229#define source_div7 (3)
230 if (clk > 500) {
231 *source = source_div3;
232 *div = 1;
233 *rclk = 667;
234 } else if (clk >= 500) {
235 *source = source_div4;
236 *div = 1;
237 *rclk = 500;
238 } else if (clk >= 400) {
239 *source = source_div5;
240 *div = 1;
241 *rclk = 400;
242 } else if (clk >= 333) {
243 *source = source_div3;
244 *div = 2;
245 *rclk = 333;
246 } else if (clk >= 200) {
247 *source = source_div5;
248 *div = 2;
249 *rclk = 200;
250 } else if (clk >= 166) {
251 *source = source_div4;
252 *div = 3;
253 *rclk = 166;
254 } else if (clk >= 133) {
255 *source = source_div5;
256 *div = 3;
257 *rclk = 133;
258 } else if (clk >= 100) {
259 *source = source_div5;
260 *div = 4;
261 *rclk = 100;
262 } else if (clk >= 50) {
263 *source = source_div5;
264 *div = 8;
265 *rclk = 50;
266 } else {
267 *source = source_div5;
268 *div = 20;
269 *rclk = 10;
270 }
271}
272EXPORT_SYMBOL(vdec_get_clk_source);
273
274
275/*
276 *enum vformat_e {
277 * VFORMAT_MPEG12 = 0,
278 * VFORMAT_MPEG4,
279 * VFORMAT_H264,
280 * VFORMAT_MJPEG,
281 * VFORMAT_REAL,
282 * VFORMAT_JPEG,
283 * VFORMAT_VC1,
284 * VFORMAT_AVS,
285 * VFORMAT_YUV,
286 * VFORMAT_H264MVC,
287 * VFORMAT_H264_4K2K,
288 * VFORMAT_HEVC,
289 * VFORMAT_H264_ENC,
290 * VFORMAT_JPEG_ENC,
291 * VFORMAT_VP9,
292 * VFORMAT_MAX
293 *};
294 *sample:
295 *{{1280*720*30, 100}, {1920*1080*30, 166}, {1920*1080*60, 333},
296 * {4096*2048*30, 600}, {4096*2048*60, 600}, {INT_MAX, 600},}
297 *mean:
298 *width * height * fps
299 *<720p30fps clk=100MHZ
300 *>=720p30fps & < 1080p30fps clk=166MHZ
301 *>=1080p 30fps & < 1080p60fps clk=333MHZ
302 */
303static struct clk_set_setting clks_for_formats[] = {
304 { /*[VFORMAT_MPEG12] */
305 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166},
306 {1920 * 1080 * 60, 333},
307 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
308 600}, {INT_MAX, 600},
309 }
310 },
311 { /*[VFORMAT_MPEG4] */
312 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166},
313 {1920 * 1080 * 60, 333},
314 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
315 600}, {INT_MAX, 600},
316 }
317 },
318 { /*[VFORMAT_H264] */
319 {{1280 * 720 * 30, 100}, {1920 * 1080 * 21, 166},
320 {1920 * 1080 * 30, 333},
321 {1920 * 1080 * 60, 600}, {4096 * 2048 * 60,
322 600}, {INT_MAX, 600},
323 }
324 },
325 { /*[VFORMAT_MJPEG] */
326 {{1280 * 720 * 30, 200}, {1920 * 1080 * 30, 200},
327 {1920 * 1080 * 60, 333},
328 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
329 600}, {INT_MAX, 600},
330 }
331 },
332 { /*[VFORMAT_REAL] */
333 {{1280 * 720 * 20, 200}, {1920 * 1080 * 30, 500},
334 {1920 * 1080 * 60, 500},
335 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
336 600}, {INT_MAX, 600},
337 }
338 },
339 { /*[VFORMAT_JPEG] */
340 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166},
341 {1920 * 1080 * 60, 333},
342 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
343 600}, {INT_MAX, 600},
344 }
345 },
346 { /*[VFORMAT_VC1] */
347 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166},
348 {1920 * 1080 * 60, 333},
349 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
350 600}, {INT_MAX, 600},
351 }
352 },
353 { /*[VFORMAT_AVS] */
354 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 166},
355 {1920 * 1080 * 60, 333},
356 {4096 * 2048 * 30, 600}, {4096 * 2048 * 60,
357 600}, {INT_MAX, 600},
358 }
359 },
360 { /*[VFORMAT_YUV] */
361 {{1280 * 720 * 30, 100}, {INT_MAX, 100},
362 {0, 0}, {0, 0}, {0, 0}, {0, 0},
363 }
364 },
365 { /*VFORMAT_H264MVC */
366 {{1280 * 720 * 30, 333}, {1920 * 1080 * 30, 333},
367 {4096 * 2048 * 60, 600},
368 {INT_MAX, 630}, {0, 0}, {0, 0},
369 }
370 },
371 { /*VFORMAT_H264_4K2K */
372 {{1280 * 720 * 30, 600}, {4096 * 2048 * 60, 630},
373 {INT_MAX, 630},
374 {0, 0}, {0, 0}, {0, 0},
375 }
376 },
377 { /*VFORMAT_HEVC */
378 {{1280 * 720 * 30, 100}, {1920 * 1080 * 60, 600},
379 {4096 * 2048 * 25, 630},
380 {4096 * 2048 * 30, 630}, {4096 * 2048 * 60,
381 630}, {INT_MAX, 630},
382 }
383 },
384 { /*VFORMAT_H264_ENC */
385 {{1280 * 720 * 30, 0}, {INT_MAX, 0},
386 {0, 0}, {0, 0}, {0, 0}, {0, 0},
387 }
388 },
389 { /*VFORMAT_JPEG_ENC */
390 {{1280 * 720 * 30, 0}, {INT_MAX, 0},
391 {0, 0}, {0, 0}, {0, 0}, {0, 0},
392 }
393 },
394 { /*VFORMAT_VP9 */
395 {{1280 * 720 * 30, 100}, {1920 * 1080 * 30, 100},
396 {1920 * 1080 * 60, 166},
397 {4096 * 2048 * 30, 333}, {4096 * 2048 * 60,
398 630}, {INT_MAX, 630},
399 }
400 },
401 {/*VFORMAT_AVS2*/
402 {{1280*720*30, 100}, {1920*1080*30, 100},
403 {1920*1080*60, 166}, {4096*2048*30, 333},
404 {4096*2048*60, 630}, {INT_MAX, 630},}
405 },
406 {/*VFORMAT_AV1*/
407 {{1280*720*30, 100}, {1920*1080*30, 100},
408 {1920*1080*60, 166}, {4096*2048*30, 333},
409 {4096*2048*60, 630}, {INT_MAX, 630},}
410 },
411
412};
413
414void set_clock_gate(struct gate_switch_node *nodes, int num)
415{
416 struct gate_switch_node *node = NULL;
417
418 do {
419 node = &nodes[num - 1];
420 if (IS_ERR_OR_NULL(node))
421 pr_info("get mux clk err.\n");
422
423 if (!strcmp(node->name, "clk_vdec_mux"))
424 gclk.vdec_mux_node = node;
425 else if (!strcmp(node->name, "clk_hcodec_mux"))
426 gclk.hcodec_mux_node = node;
427 else if (!strcmp(node->name, "clk_hevc_mux"))
428 gclk.hevc_mux_node = node;
429 else if (!strcmp(node->name, "clk_hevcb_mux"))
430 gclk.hevc_back_mux_node = node;
431 } while(--num);
432}
433EXPORT_SYMBOL(set_clock_gate);
434#ifdef NO_CLKTREE
435int vdec_set_clk(int dec, int source, int div)
436{
437
438 if (dec == VDEC_1)
439 vdec1_set_clk(source, div);
440 else if (dec == VDEC_2)
441 vdec2_set_clk(source, div);
442 else if (dec == VDEC_HEVC)
443 hevc_set_clk(source, div);
444 else if (dec == VDEC_HCODEC)
445 hcodec_set_clk(source, div);
446 return 0;
447}
448
449#else
450static int vdec_set_clk(int dec, int rate)
451{
452 struct clk *clk = NULL;
453
454 switch (dec) {
455 case VDEC_1:
456 clk = gclk.vdec_mux_node->clk;
457 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10);
458 break;
459
460 case VDEC_HCODEC:
461 clk = gclk.hcodec_mux_node->clk;
462 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);
463 break;
464
465 case VDEC_2:
466 clk = gclk.vdec_mux_node->clk;
467 WRITE_VREG(DOS_GCLK_EN1, 0x3ff);
468 break;
469
470 case VDEC_HEVC:
471 clk = gclk.hevc_mux_node->clk;
472 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
473 break;
474
475 case VDEC_HEVCB:
476 clk = gclk.hevc_back_mux_node->clk;
477 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
478 break;
479
480 case VDEC_MAX:
481 break;
482
483 default:
484 pr_info("invaild vdec type.\n");
485 }
486
487 if (IS_ERR_OR_NULL(clk)) {
488 pr_info("the mux clk err.\n");
489 return -1;
490 }
491
492 clk_set_rate(clk, rate);
493
494 return 0;
495}
496
497static int vdec_clock_init(void)
498{
499 return 0;
500}
501
502#endif
503#ifdef NO_CLKTREE
504static int vdec_clock_init(void)
505{
506 gp_pll_user_vdec = gp_pll_user_register("vdec", 0,
507 gp_pll_user_cb_vdec);
508 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL)
509 is_gp0_div2 = false;
510 else
511 is_gp0_div2 = true;
512
513 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) {
514 pr_info("used fix clk for vdec clk source!\n");
515 //update_vdec_clk_config_settings(1);
516 }
517 return (gp_pll_user_vdec) ? 0 : -ENOMEM;
518}
519
520
521
522static void update_clk_with_clk_configs(
523 int clk, int *source, int *div, int *rclk)
524{
525 unsigned int config = 0;//get_vdec_clk_config_settings();
526
527 if (!config)
528 return;
529 if (config >= 10) {
530 int wantclk;
531 wantclk = config;
532 vdec_get_clk_source(wantclk, source, div, rclk);
533 }
534 return;
535}
536#define NO_GP0_PLL 0//(get_vdec_clk_config_settings() == 1)
537#define ALWAYS_GP0_PLL 0//(get_vdec_clk_config_settings() == 2)
538
539#define NO_GP0_PLL 0//(get_vdec_clk_config_settings() == 1)
540#define ALWAYS_GP0_PLL 0//(get_vdec_clk_config_settings() == 2)
541
542static int vdec_clock_set(int clk)
543{
544 int use_gpll = 0;
545 int source, div, rclk;
546 int clk_seted = 0;
547 int gp_pll_wait = 0;
548 if (clk == 1)
549 clk = 200;
550 else if (clk == 2) {
551 if (clock_real_clk[VDEC_1] != 648)
552 clk = 500;
553 else
554 clk = 648;
555 } else if (clk == 0) {
556 /*used for release gp pull.
557 if used, release it.
558 if not used gp pll
559 do nothing.
560 */
561 if (clock_real_clk[VDEC_1] == 667 ||
562 (clock_real_clk[VDEC_1] == 648) ||
563 clock_real_clk[VDEC_1] <= 0)
564 clk = 200;
565 else
566 clk = clock_real_clk[VDEC_1];
567 }
568 vdec_get_clk_source(clk, &source, &div, &rclk);
569 update_clk_with_clk_configs(clk, &source, &div, &rclk);
570
571 if (clock_real_clk[VDEC_1] == rclk)
572 return rclk;
573 if (NO_GP0_PLL) {
574 use_gpll = 0;
575 clk_seted = 0;
576 } else if ((rclk > 500 && clk != 667) || ALWAYS_GP0_PLL) {
577 if (clock_real_clk[VDEC_1] == 648)
578 return 648;
579 use_gpll = 1;
580 gp_pll_request(gp_pll_user_vdec);
581 while (!VDEC1_WITH_GP_PLL() && gp_pll_wait++ < 1000000)
582 udelay(1);
583 if (VDEC1_WITH_GP_PLL()) {
584 clk_seted = 1;
585 rclk = 648;
586 } else {
587 use_gpll = 0;
588 rclk = 667;
589 /*gp_pull request failed,used default 500Mhz*/
590 pr_info("get gp pll failed used fix pull\n");
591 }
592 }
593 if (!clk_seted) {/*if 648 not set,*/
594 VDEC1_SAFE_CLOCK();
595 VDEC1_CLOCK_OFF();
596 vdec_set_clk(VDEC_1, source, div);
597 VDEC1_CLOCK_ON();
598 }
599
600 if (!use_gpll)
601 gp_pll_release(gp_pll_user_vdec);
602 clock_real_clk[VDEC_1] = rclk;
603 debug_print("vdec_clock_set 2 to %d\n", rclk);
604 return rclk;
605}
606static int hevc_clock_init(void)
607{
608 gp_pll_user_hevc = gp_pll_user_register("hevc", 0,
609 gp_pll_user_cb_hevc);
610
611 return (gp_pll_user_hevc) ? 0 : -ENOMEM;
612}
613static int hevc_back_clock_init(void)
614{
615 return 0;
616}
617
618static int hevc_back_clock_set(int clk)
619{
620 return 0;
621}
622
623static int hevc_clock_set(int clk)
624{
625 int use_gpll = 0;
626 int source, div, rclk;
627 int gp_pll_wait = 0;
628 int clk_seted = 0;
629
630 debug_print("hevc_clock_set 1 to clk %d\n", clk);
631 if (clk == 1)
632 clk = 200;
633 else if (clk == 2) {
634 if (clock_real_clk[VDEC_HEVC] != 648)
635 clk = 500;
636 else
637 clk = 648;
638 } else if (clk == 0) {
639 /*used for release gp pull.
640 if used, release it.
641 if not used gp pll
642 do nothing.
643 */
644 if ((clock_real_clk[VDEC_HEVC] == 667) ||
645 (clock_real_clk[VDEC_HEVC] == 648) ||
646 (clock_real_clk[VDEC_HEVC] <= 0))
647 clk = 200;
648 else
649 clk = clock_real_clk[VDEC_HEVC];
650 }
651 vdec_get_clk_source(clk, &source, &div, &rclk);
652 update_clk_with_clk_configs(clk, &source, &div, &rclk);
653
654 if (rclk == clock_real_clk[VDEC_HEVC])
655 return rclk;/*clk not changed,*/
656 if (NO_GP0_PLL) {
657 use_gpll = 0;
658 clk_seted = 0;
659 } else if ((rclk > 500 && clk != 667) || ALWAYS_GP0_PLL) {
660 if (clock_real_clk[VDEC_HEVC] == 648)
661 return 648;
662 use_gpll = 1;
663 gp_pll_request(gp_pll_user_hevc);
664 while (!HEVC_WITH_GP_PLL() && gp_pll_wait++ < 1000000)
665 udelay(1);
666 if (HEVC_WITH_GP_PLL()) {
667 clk_seted = 1;
668 rclk = 648;
669 } else {
670 rclk = 667;
671 /*gp_pull request failed,used default 500Mhz*/
672 pr_info("get gp pll failed used fix pull\n");
673 }
674 }
675 if (!clk_seted) {/*if 648 not set,*/
676// HEVC_SAFE_CLOCK();
677 HEVC_CLOCK_OFF();
678 vdec_set_clk(VDEC_HEVC, source, div);
679 HEVC_CLOCK_ON();
680 }
681 if (!use_gpll)
682 gp_pll_release(gp_pll_user_hevc);
683 clock_real_clk[VDEC_HEVC] = rclk;
684 /*debug_print("hevc_clock_set 2 to rclk=%d, configs=%d\n",
685 rclk,
686 get_vdec_clk_config_settings());*/ //DEBUG_TMP
687 return rclk;
688}
689
690static int hcodec_clock_set(int clk)
691{
692 int source, div, rclk;
693 HCODEC_CLOCK_OFF();
694 vdec_get_clk_source(200, &source, &div, &rclk);
695 vdec_set_clk(VDEC_HCODEC, source, div);
696 HCODEC_CLOCK_ON();
697 clock_real_clk[VDEC_HCODEC] = rclk;
698 return rclk;
699}
700
701
702#else
703static int vdec_clock_set(int clk)
704{
705 if (clk == 1)
706 clk = 200;
707 else if (clk == 2) {
708 if (clock_real_clk[VDEC_1] != 648)
709 clk = 500;
710 else
711 clk = 648;
712 } else if (clk == 0) {
713 if (clock_real_clk[VDEC_1] == 667 ||
714 (clock_real_clk[VDEC_1] == 648) ||
715 clock_real_clk[VDEC_1] <= 0)
716 clk = 200;
717 else
718 clk = clock_real_clk[VDEC_1];
719 }
720
721 if ((clk > 500 && clk != 667)) {
722 if (clock_real_clk[VDEC_1] == 648)
723 return 648;
724 clk = 667;
725 }
726
727 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1 &&
728 get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)
729 clk = 800;
730
731 if (set_frq_enable && vdec_frq) {
732 pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
733 clk = vdec_frq;
734 }
735
736 vdec_set_clk(VDEC_1, clk * MHz);
737
738 clock_real_clk[VDEC_1] = clk;
739
740 pr_debug("vdec mux clock is %lu Hz\n",
741 clk_get_rate(gclk.vdec_mux_node->clk));
742
743 return clk;
744}
745
746static int hevc_clock_init(void)
747{
748 return 0;
749}
750
751static int hevc_back_clock_init(void)
752{
753 return 0;
754}
755
756static int hevc_back_clock_set(int clk)
757{
758 if (clk == 1)
759 clk = 200;
760 else if (clk == 2) {
761 if (clock_real_clk[VDEC_HEVCB] != 648)
762 clk = 500;
763 else
764 clk = 648;
765 } else if (clk == 0) {
766 if (clock_real_clk[VDEC_HEVCB] == 667 ||
767 (clock_real_clk[VDEC_HEVCB] == 648) ||
768 clock_real_clk[VDEC_HEVCB] <= 0)
769 clk = 200;
770 else
771 clk = clock_real_clk[VDEC_HEVCB];
772 }
773
774 if ((clk > 500 && clk != 667)) {
775 if (clock_real_clk[VDEC_HEVCB] == 648)
776 return 648;
777 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
778 clk = TL1_HEVC_MAX_CLK;
779 else
780 clk = 667;
781 }
782
783 if (set_frq_enable && hevcb_frq) {
784 pr_info("Set the hevcb frq is %u MHz\n", hevcb_frq);
785 clk = hevcb_frq;
786 }
787
788 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_TXLX) {
789 if ((READ_EFUSE_REG(EFUSE_LIC1) >> 28 & 0x1) && clk > 333) {
790 pr_info("The hevcb clock limit to 333MHz.\n");
791 clk = 333;
792 }
793 }
794
795 vdec_set_clk(VDEC_HEVCB, clk * MHz);
796
797 clock_real_clk[VDEC_HEVCB] = clk;
798 pr_debug("hevc back mux clock is %lu Hz\n",
799 clk_get_rate(gclk.hevc_back_mux_node->clk));
800
801 return clk;
802}
803
804static int hevc_clock_set(int clk)
805{
806 if (clk == 1)
807 clk = 200;
808 else if (clk == 2) {
809 if (clock_real_clk[VDEC_HEVC] != 648)
810 clk = 500;
811 else
812 clk = 648;
813 } else if (clk == 0) {
814 if (clock_real_clk[VDEC_HEVC] == 667 ||
815 (clock_real_clk[VDEC_HEVC] == 648) ||
816 clock_real_clk[VDEC_HEVC] <= 0)
817 clk = 200;
818 else
819 clk = clock_real_clk[VDEC_HEVC];
820 }
821
822 if ((clk > 500 && clk != 667)) {
823 if (clock_real_clk[VDEC_HEVC] == 648)
824 return 648;
825 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
826 clk = TL1_HEVC_MAX_CLK;
827 else
828 clk = 667;
829 }
830
831 if (set_frq_enable && hevc_frq) {
832 pr_info("Set the hevc frq is %u MHz\n", hevc_frq);
833 clk = hevc_frq;
834 }
835
836 vdec_set_clk(VDEC_HEVC, clk * MHz);
837
838 clock_real_clk[VDEC_HEVC] = clk;
839
840 pr_debug("hevc mux clock is %lu Hz\n",
841 clk_get_rate(gclk.hevc_mux_node->clk));
842
843 return clk;
844}
845
846static int hcodec_clock_set(int clk)
847{
848 if (clk == 1)
849 clk = 200;
850 else if (clk == 2) {
851 if (clock_real_clk[VDEC_HCODEC] != 648)
852 clk = 500;
853 else
854 clk = 648;
855 } else if (clk == 0) {
856 if (clock_real_clk[VDEC_HCODEC] == 667 ||
857 (clock_real_clk[VDEC_HCODEC] == 648) ||
858 clock_real_clk[VDEC_HCODEC] <= 0)
859 clk = 200;
860 else
861 clk = clock_real_clk[VDEC_HCODEC];
862 }
863
864 if ((clk > 500 && clk != 667)) {
865 if (clock_real_clk[VDEC_HCODEC] == 648)
866 return 648;
867 clk = 667;
868 }
869
870 vdec_set_clk(VDEC_HCODEC, clk * MHz);
871
872 clock_real_clk[VDEC_HCODEC] = clk;
873
874 pr_debug("hcodec mux clock is %lu Hz\n",
875 clk_get_rate(gclk.hcodec_mux_node->clk));
876
877 return clk;
878}
879#endif
880
881static void vdec_clock_on(void)
882{
883 mutex_lock(&gclk.vdec_mux_node->mutex);
884 if (!gclk.vdec_mux_node->ref_count)
885 clk_prepare_enable(gclk.vdec_mux_node->clk);
886
887 gclk.vdec_mux_node->ref_count++;
888 mutex_unlock(&gclk.vdec_mux_node->mutex);
889
890 pr_debug("the %-15s clock on, ref cnt: %d\n",
891 gclk.vdec_mux_node->name,
892 gclk.vdec_mux_node->ref_count);
893}
894
895static void vdec_clock_off(void)
896{
897 mutex_lock(&gclk.vdec_mux_node->mutex);
898 gclk.vdec_mux_node->ref_count--;
899 if (!gclk.vdec_mux_node->ref_count)
900 clk_disable_unprepare(gclk.vdec_mux_node->clk);
901
902 clock_real_clk[VDEC_1] = 0;
903 mutex_unlock(&gclk.vdec_mux_node->mutex);
904
905 pr_debug("the %-15s clock off, ref cnt: %d\n",
906 gclk.vdec_mux_node->name,
907 gclk.vdec_mux_node->ref_count);
908}
909
910static void hcodec_clock_on(void)
911{
912 mutex_lock(&gclk.hcodec_mux_node->mutex);
913 if (!gclk.hcodec_mux_node->ref_count)
914 clk_prepare_enable(gclk.hcodec_mux_node->clk);
915
916 gclk.hcodec_mux_node->ref_count++;
917 mutex_unlock(&gclk.hcodec_mux_node->mutex);
918
919 pr_debug("the %-15s clock on, ref cnt: %d\n",
920 gclk.hcodec_mux_node->name,
921 gclk.hcodec_mux_node->ref_count);
922}
923
924static void hcodec_clock_off(void)
925{
926 mutex_lock(&gclk.hcodec_mux_node->mutex);
927 gclk.hcodec_mux_node->ref_count--;
928 if (!gclk.hcodec_mux_node->ref_count)
929 clk_disable_unprepare(gclk.hcodec_mux_node->clk);
930
931 mutex_unlock(&gclk.hcodec_mux_node->mutex);
932
933 pr_debug("the %-15s clock off, ref cnt: %d\n",
934 gclk.hcodec_mux_node->name,
935 gclk.hcodec_mux_node->ref_count);
936}
937
938static void hevc_clock_on(void)
939{
940 mutex_lock(&gclk.hevc_mux_node->mutex);
941 if (!gclk.hevc_mux_node->ref_count)
942 clk_prepare_enable(gclk.hevc_mux_node->clk);
943
944 gclk.hevc_mux_node->ref_count++;
945 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
946 mutex_unlock(&gclk.hevc_mux_node->mutex);
947
948 pr_debug("the %-15s clock on, ref cnt: %d\n",
949 gclk.hevc_mux_node->name,
950 gclk.hevc_mux_node->ref_count);
951}
952
953static void hevc_clock_off(void)
954{
955 mutex_lock(&gclk.hevc_mux_node->mutex);
956 gclk.hevc_mux_node->ref_count--;
957 if (!gclk.hevc_mux_node->ref_count)
958 clk_disable_unprepare(gclk.hevc_mux_node->clk);
959
960 clock_real_clk[VDEC_HEVC] = 0;
961 mutex_unlock(&gclk.hevc_mux_node->mutex);
962
963 pr_debug("the %-15s clock off, ref cnt: %d\n",
964 gclk.hevc_mux_node->name,
965 gclk.hevc_mux_node->ref_count);
966}
967
968static void hevc_back_clock_on(void)
969{
970 mutex_lock(&gclk.hevc_back_mux_node->mutex);
971 if (!gclk.hevc_back_mux_node->ref_count)
972 clk_prepare_enable(gclk.hevc_back_mux_node->clk);
973
974 gclk.hevc_back_mux_node->ref_count++;
975 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
976 mutex_unlock(&gclk.hevc_back_mux_node->mutex);
977
978 pr_debug("the %-15s clock on, ref cnt: %d\n",
979 gclk.hevc_back_mux_node->name,
980 gclk.hevc_back_mux_node->ref_count);
981}
982
983static void hevc_back_clock_off(void)
984{
985 mutex_lock(&gclk.hevc_back_mux_node->mutex);
986 gclk.hevc_back_mux_node->ref_count--;
987 if (!gclk.hevc_back_mux_node->ref_count)
988 clk_disable_unprepare(gclk.hevc_back_mux_node->clk);
989
990 clock_real_clk[VDEC_HEVC] = 0;
991 mutex_unlock(&gclk.hevc_back_mux_node->mutex);
992
993 pr_debug("the %-15s clock off, ref cnt: %d\n",
994 gclk.hevc_back_mux_node->name,
995 gclk.hevc_back_mux_node->ref_count);
996}
997
998static int vdec_clock_get(enum vdec_type_e core)
999{
1000 if (core >= VDEC_MAX)
1001 return 0;
1002
1003 return clock_real_clk[core];
1004}
1005
1006#define INCLUDE_FROM_ARCH_CLK_MGR
1007
1008/*#define VDEC_HAS_VDEC2*/
1009#define VDEC_HAS_HEVC
1010#define VDEC_HAS_VDEC_HCODEC
1011#define VDEC_HAS_CLK_SETTINGS
1012#define CLK_FOR_CPU {\
1013 AM_MESON_CPU_MAJOR_ID_GXBB,\
1014 AM_MESON_CPU_MAJOR_ID_GXTVBB,\
1015 AM_MESON_CPU_MAJOR_ID_GXL,\
1016 AM_MESON_CPU_MAJOR_ID_GXM,\
1017 AM_MESON_CPU_MAJOR_ID_TXL,\
1018 AM_MESON_CPU_MAJOR_ID_TXLX,\
1019 AM_MESON_CPU_MAJOR_ID_G12A,\
1020 AM_MESON_CPU_MAJOR_ID_G12B,\
1021 AM_MESON_CPU_MAJOR_ID_SM1,\
1022 AM_MESON_CPU_MAJOR_ID_TL1,\
1023 AM_MESON_CPU_MAJOR_ID_TM2,\
1024 0}
1025#include "clk.h"
1026
1027module_param(set_frq_enable, uint, 0664);
1028MODULE_PARM_DESC(set_frq_enable, "\n set frequency enable\n");
1029
1030module_param(vdec_frq, uint, 0664);
1031MODULE_PARM_DESC(vdec_frq, "\n set vdec frequency\n");
1032
1033module_param(hevc_frq, uint, 0664);
1034MODULE_PARM_DESC(hevc_frq, "\n set hevc frequency\n");
1035
1036module_param(hevcb_frq, uint, 0664);
1037MODULE_PARM_DESC(hevcb_frq, "\n set hevcb frequency\n");
1038
1039ARCH_VDEC_CLK_INIT();
1040ARCH_VDEC_CLK_EXIT();
1041
1042MODULE_LICENSE("GPL");
1043