summaryrefslogtreecommitdiff
path: root/drivers/common/media_clock/clk/clkg12.c (plain)
blob: f045bd3208892d58e2d6aef6f6e4923c86eb153e
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
407};
408
409void set_clock_gate(struct gate_switch_node *nodes, int num)
410{
411 struct gate_switch_node *node = NULL;
412
413 do {
414 node = &nodes[num - 1];
415 if (IS_ERR_OR_NULL(node))
416 pr_info("get mux clk err.\n");
417
418 if (!strcmp(node->name, "clk_vdec_mux"))
419 gclk.vdec_mux_node = node;
420 else if (!strcmp(node->name, "clk_hcodec_mux"))
421 gclk.hcodec_mux_node = node;
422 else if (!strcmp(node->name, "clk_hevc_mux"))
423 gclk.hevc_mux_node = node;
424 else if (!strcmp(node->name, "clk_hevcb_mux"))
425 gclk.hevc_back_mux_node = node;
426 } while(--num);
427}
428EXPORT_SYMBOL(set_clock_gate);
429#ifdef NO_CLKTREE
430int vdec_set_clk(int dec, int source, int div)
431{
432
433 if (dec == VDEC_1)
434 vdec1_set_clk(source, div);
435 else if (dec == VDEC_2)
436 vdec2_set_clk(source, div);
437 else if (dec == VDEC_HEVC)
438 hevc_set_clk(source, div);
439 else if (dec == VDEC_HCODEC)
440 hcodec_set_clk(source, div);
441 return 0;
442}
443
444#else
445static int vdec_set_clk(int dec, int rate)
446{
447 struct clk *clk = NULL;
448
449 switch (dec) {
450 case VDEC_1:
451 clk = gclk.vdec_mux_node->clk;
452 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x3ff, 0, 10);
453 break;
454
455 case VDEC_HCODEC:
456 clk = gclk.hcodec_mux_node->clk;
457 WRITE_VREG_BITS(DOS_GCLK_EN0, 0x7fff, 12, 15);
458 break;
459
460 case VDEC_2:
461 clk = gclk.vdec_mux_node->clk;
462 WRITE_VREG(DOS_GCLK_EN1, 0x3ff);
463 break;
464
465 case VDEC_HEVC:
466 clk = gclk.hevc_mux_node->clk;
467 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
468 break;
469
470 case VDEC_HEVCB:
471 clk = gclk.hevc_back_mux_node->clk;
472 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
473 break;
474
475 case VDEC_MAX:
476 break;
477
478 default:
479 pr_info("invaild vdec type.\n");
480 }
481
482 if (IS_ERR_OR_NULL(clk)) {
483 pr_info("the mux clk err.\n");
484 return -1;
485 }
486
487 clk_set_rate(clk, rate);
488
489 return 0;
490}
491
492static int vdec_clock_init(void)
493{
494 return 0;
495}
496
497#endif
498#ifdef NO_CLKTREE
499static int vdec_clock_init(void)
500{
501 gp_pll_user_vdec = gp_pll_user_register("vdec", 0,
502 gp_pll_user_cb_vdec);
503 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL)
504 is_gp0_div2 = false;
505 else
506 is_gp0_div2 = true;
507
508 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_GXL) {
509 pr_info("used fix clk for vdec clk source!\n");
510 //update_vdec_clk_config_settings(1);
511 }
512 return (gp_pll_user_vdec) ? 0 : -ENOMEM;
513}
514
515
516
517static void update_clk_with_clk_configs(
518 int clk, int *source, int *div, int *rclk)
519{
520 unsigned int config = 0;//get_vdec_clk_config_settings();
521
522 if (!config)
523 return;
524 if (config >= 10) {
525 int wantclk;
526 wantclk = config;
527 vdec_get_clk_source(wantclk, source, div, rclk);
528 }
529 return;
530}
531#define NO_GP0_PLL 0//(get_vdec_clk_config_settings() == 1)
532#define ALWAYS_GP0_PLL 0//(get_vdec_clk_config_settings() == 2)
533
534#define NO_GP0_PLL 0//(get_vdec_clk_config_settings() == 1)
535#define ALWAYS_GP0_PLL 0//(get_vdec_clk_config_settings() == 2)
536
537static int vdec_clock_set(int clk)
538{
539 int use_gpll = 0;
540 int source, div, rclk;
541 int clk_seted = 0;
542 int gp_pll_wait = 0;
543 if (clk == 1)
544 clk = 200;
545 else if (clk == 2) {
546 if (clock_real_clk[VDEC_1] != 648)
547 clk = 500;
548 else
549 clk = 648;
550 } else if (clk == 0) {
551 /*used for release gp pull.
552 if used, release it.
553 if not used gp pll
554 do nothing.
555 */
556 if (clock_real_clk[VDEC_1] == 667 ||
557 (clock_real_clk[VDEC_1] == 648) ||
558 clock_real_clk[VDEC_1] <= 0)
559 clk = 200;
560 else
561 clk = clock_real_clk[VDEC_1];
562 }
563 vdec_get_clk_source(clk, &source, &div, &rclk);
564 update_clk_with_clk_configs(clk, &source, &div, &rclk);
565
566 if (clock_real_clk[VDEC_1] == rclk)
567 return rclk;
568 if (NO_GP0_PLL) {
569 use_gpll = 0;
570 clk_seted = 0;
571 } else if ((rclk > 500 && clk != 667) || ALWAYS_GP0_PLL) {
572 if (clock_real_clk[VDEC_1] == 648)
573 return 648;
574 use_gpll = 1;
575 gp_pll_request(gp_pll_user_vdec);
576 while (!VDEC1_WITH_GP_PLL() && gp_pll_wait++ < 1000000)
577 udelay(1);
578 if (VDEC1_WITH_GP_PLL()) {
579 clk_seted = 1;
580 rclk = 648;
581 } else {
582 use_gpll = 0;
583 rclk = 667;
584 /*gp_pull request failed,used default 500Mhz*/
585 pr_info("get gp pll failed used fix pull\n");
586 }
587 }
588 if (!clk_seted) {/*if 648 not set,*/
589 VDEC1_SAFE_CLOCK();
590 VDEC1_CLOCK_OFF();
591 vdec_set_clk(VDEC_1, source, div);
592 VDEC1_CLOCK_ON();
593 }
594
595 if (!use_gpll)
596 gp_pll_release(gp_pll_user_vdec);
597 clock_real_clk[VDEC_1] = rclk;
598 debug_print("vdec_clock_set 2 to %d\n", rclk);
599 return rclk;
600}
601static int hevc_clock_init(void)
602{
603 gp_pll_user_hevc = gp_pll_user_register("hevc", 0,
604 gp_pll_user_cb_hevc);
605
606 return (gp_pll_user_hevc) ? 0 : -ENOMEM;
607}
608static int hevc_back_clock_init(void)
609{
610 return 0;
611}
612
613static int hevc_back_clock_set(int clk)
614{
615 return 0;
616}
617
618static int hevc_clock_set(int clk)
619{
620 int use_gpll = 0;
621 int source, div, rclk;
622 int gp_pll_wait = 0;
623 int clk_seted = 0;
624
625 debug_print("hevc_clock_set 1 to clk %d\n", clk);
626 if (clk == 1)
627 clk = 200;
628 else if (clk == 2) {
629 if (clock_real_clk[VDEC_HEVC] != 648)
630 clk = 500;
631 else
632 clk = 648;
633 } else if (clk == 0) {
634 /*used for release gp pull.
635 if used, release it.
636 if not used gp pll
637 do nothing.
638 */
639 if ((clock_real_clk[VDEC_HEVC] == 667) ||
640 (clock_real_clk[VDEC_HEVC] == 648) ||
641 (clock_real_clk[VDEC_HEVC] <= 0))
642 clk = 200;
643 else
644 clk = clock_real_clk[VDEC_HEVC];
645 }
646 vdec_get_clk_source(clk, &source, &div, &rclk);
647 update_clk_with_clk_configs(clk, &source, &div, &rclk);
648
649 if (rclk == clock_real_clk[VDEC_HEVC])
650 return rclk;/*clk not changed,*/
651 if (NO_GP0_PLL) {
652 use_gpll = 0;
653 clk_seted = 0;
654 } else if ((rclk > 500 && clk != 667) || ALWAYS_GP0_PLL) {
655 if (clock_real_clk[VDEC_HEVC] == 648)
656 return 648;
657 use_gpll = 1;
658 gp_pll_request(gp_pll_user_hevc);
659 while (!HEVC_WITH_GP_PLL() && gp_pll_wait++ < 1000000)
660 udelay(1);
661 if (HEVC_WITH_GP_PLL()) {
662 clk_seted = 1;
663 rclk = 648;
664 } else {
665 rclk = 667;
666 /*gp_pull request failed,used default 500Mhz*/
667 pr_info("get gp pll failed used fix pull\n");
668 }
669 }
670 if (!clk_seted) {/*if 648 not set,*/
671// HEVC_SAFE_CLOCK();
672 HEVC_CLOCK_OFF();
673 vdec_set_clk(VDEC_HEVC, source, div);
674 HEVC_CLOCK_ON();
675 }
676 if (!use_gpll)
677 gp_pll_release(gp_pll_user_hevc);
678 clock_real_clk[VDEC_HEVC] = rclk;
679 /*debug_print("hevc_clock_set 2 to rclk=%d, configs=%d\n",
680 rclk,
681 get_vdec_clk_config_settings());*/ //DEBUG_TMP
682 return rclk;
683}
684
685static int hcodec_clock_set(int clk)
686{
687 int source, div, rclk;
688 HCODEC_CLOCK_OFF();
689 vdec_get_clk_source(200, &source, &div, &rclk);
690 vdec_set_clk(VDEC_HCODEC, source, div);
691 HCODEC_CLOCK_ON();
692 clock_real_clk[VDEC_HCODEC] = rclk;
693 return rclk;
694}
695
696
697#else
698static int vdec_clock_set(int clk)
699{
700 if (clk == 1)
701 clk = 200;
702 else if (clk == 2) {
703 if (clock_real_clk[VDEC_1] != 648)
704 clk = 500;
705 else
706 clk = 648;
707 } else if (clk == 0) {
708 if (clock_real_clk[VDEC_1] == 667 ||
709 (clock_real_clk[VDEC_1] == 648) ||
710 clock_real_clk[VDEC_1] <= 0)
711 clk = 200;
712 else
713 clk = clock_real_clk[VDEC_1];
714 }
715
716 if ((clk > 500 && clk != 667)) {
717 if (clock_real_clk[VDEC_1] == 648)
718 return 648;
719 clk = 667;
720 }
721
722 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1 &&
723 get_cpu_major_id() != AM_MESON_CPU_MAJOR_ID_TL1)
724 clk = 800;
725
726 if (set_frq_enable && vdec_frq) {
727 pr_info("Set the vdec frq is %u MHz\n", vdec_frq);
728 clk = vdec_frq;
729 }
730
731 vdec_set_clk(VDEC_1, clk * MHz);
732
733 clock_real_clk[VDEC_1] = clk;
734
735 pr_debug("vdec mux clock is %lu Hz\n",
736 clk_get_rate(gclk.vdec_mux_node->clk));
737
738 return clk;
739}
740
741static int hevc_clock_init(void)
742{
743 return 0;
744}
745
746static int hevc_back_clock_init(void)
747{
748 return 0;
749}
750
751static int hevc_back_clock_set(int clk)
752{
753 if (clk == 1)
754 clk = 200;
755 else if (clk == 2) {
756 if (clock_real_clk[VDEC_HEVCB] != 648)
757 clk = 500;
758 else
759 clk = 648;
760 } else if (clk == 0) {
761 if (clock_real_clk[VDEC_HEVCB] == 667 ||
762 (clock_real_clk[VDEC_HEVCB] == 648) ||
763 clock_real_clk[VDEC_HEVCB] <= 0)
764 clk = 200;
765 else
766 clk = clock_real_clk[VDEC_HEVCB];
767 }
768
769 if ((clk > 500 && clk != 667)) {
770 if (clock_real_clk[VDEC_HEVCB] == 648)
771 return 648;
772 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
773 clk = TL1_HEVC_MAX_CLK;
774 else
775 clk = 667;
776 }
777
778 if (set_frq_enable && hevcb_frq) {
779 pr_info("Set the hevcb frq is %u MHz\n", hevcb_frq);
780 clk = hevcb_frq;
781 }
782
783 if (get_cpu_major_id() >= MESON_CPU_MAJOR_ID_TXLX) {
784 if ((READ_EFUSE_REG(EFUSE_LIC1) >> 28 & 0x1) && clk > 333) {
785 pr_info("The hevcb clock limit to 333MHz.\n");
786 clk = 333;
787 }
788 }
789
790 vdec_set_clk(VDEC_HEVCB, clk * MHz);
791
792 clock_real_clk[VDEC_HEVCB] = clk;
793 pr_debug("hevc back mux clock is %lu Hz\n",
794 clk_get_rate(gclk.hevc_back_mux_node->clk));
795
796 return clk;
797}
798
799static int hevc_clock_set(int clk)
800{
801 if (clk == 1)
802 clk = 200;
803 else if (clk == 2) {
804 if (clock_real_clk[VDEC_HEVC] != 648)
805 clk = 500;
806 else
807 clk = 648;
808 } else if (clk == 0) {
809 if (clock_real_clk[VDEC_HEVC] == 667 ||
810 (clock_real_clk[VDEC_HEVC] == 648) ||
811 clock_real_clk[VDEC_HEVC] <= 0)
812 clk = 200;
813 else
814 clk = clock_real_clk[VDEC_HEVC];
815 }
816
817 if ((clk > 500 && clk != 667)) {
818 if (clock_real_clk[VDEC_HEVC] == 648)
819 return 648;
820 if (get_cpu_major_id() >= AM_MESON_CPU_MAJOR_ID_SM1)
821 clk = TL1_HEVC_MAX_CLK;
822 else
823 clk = 667;
824 }
825
826 if (set_frq_enable && hevc_frq) {
827 pr_info("Set the hevc frq is %u MHz\n", hevc_frq);
828 clk = hevc_frq;
829 }
830
831 vdec_set_clk(VDEC_HEVC, clk * MHz);
832
833 clock_real_clk[VDEC_HEVC] = clk;
834
835 pr_debug("hevc mux clock is %lu Hz\n",
836 clk_get_rate(gclk.hevc_mux_node->clk));
837
838 return clk;
839}
840
841static int hcodec_clock_set(int clk)
842{
843 if (clk == 1)
844 clk = 200;
845 else if (clk == 2) {
846 if (clock_real_clk[VDEC_HCODEC] != 648)
847 clk = 500;
848 else
849 clk = 648;
850 } else if (clk == 0) {
851 if (clock_real_clk[VDEC_HCODEC] == 667 ||
852 (clock_real_clk[VDEC_HCODEC] == 648) ||
853 clock_real_clk[VDEC_HCODEC] <= 0)
854 clk = 200;
855 else
856 clk = clock_real_clk[VDEC_HCODEC];
857 }
858
859 if ((clk > 500 && clk != 667)) {
860 if (clock_real_clk[VDEC_HCODEC] == 648)
861 return 648;
862 clk = 667;
863 }
864
865 vdec_set_clk(VDEC_HCODEC, clk * MHz);
866
867 clock_real_clk[VDEC_HCODEC] = clk;
868
869 pr_debug("hcodec mux clock is %lu Hz\n",
870 clk_get_rate(gclk.hcodec_mux_node->clk));
871
872 return clk;
873}
874#endif
875
876static void vdec_clock_on(void)
877{
878 mutex_lock(&gclk.vdec_mux_node->mutex);
879 if (!gclk.vdec_mux_node->ref_count)
880 clk_prepare_enable(gclk.vdec_mux_node->clk);
881
882 gclk.vdec_mux_node->ref_count++;
883 mutex_unlock(&gclk.vdec_mux_node->mutex);
884
885 pr_debug("the %-15s clock on, ref cnt: %d\n",
886 gclk.vdec_mux_node->name,
887 gclk.vdec_mux_node->ref_count);
888}
889
890static void vdec_clock_off(void)
891{
892 mutex_lock(&gclk.vdec_mux_node->mutex);
893 gclk.vdec_mux_node->ref_count--;
894 if (!gclk.vdec_mux_node->ref_count)
895 clk_disable_unprepare(gclk.vdec_mux_node->clk);
896
897 clock_real_clk[VDEC_1] = 0;
898 mutex_unlock(&gclk.vdec_mux_node->mutex);
899
900 pr_debug("the %-15s clock off, ref cnt: %d\n",
901 gclk.vdec_mux_node->name,
902 gclk.vdec_mux_node->ref_count);
903}
904
905static void hcodec_clock_on(void)
906{
907 mutex_lock(&gclk.hcodec_mux_node->mutex);
908 if (!gclk.hcodec_mux_node->ref_count)
909 clk_prepare_enable(gclk.hcodec_mux_node->clk);
910
911 gclk.hcodec_mux_node->ref_count++;
912 mutex_unlock(&gclk.hcodec_mux_node->mutex);
913
914 pr_debug("the %-15s clock on, ref cnt: %d\n",
915 gclk.hcodec_mux_node->name,
916 gclk.hcodec_mux_node->ref_count);
917}
918
919static void hcodec_clock_off(void)
920{
921 mutex_lock(&gclk.hcodec_mux_node->mutex);
922 gclk.hcodec_mux_node->ref_count--;
923 if (!gclk.hcodec_mux_node->ref_count)
924 clk_disable_unprepare(gclk.hcodec_mux_node->clk);
925
926 mutex_unlock(&gclk.hcodec_mux_node->mutex);
927
928 pr_debug("the %-15s clock off, ref cnt: %d\n",
929 gclk.hcodec_mux_node->name,
930 gclk.hcodec_mux_node->ref_count);
931}
932
933static void hevc_clock_on(void)
934{
935 mutex_lock(&gclk.hevc_mux_node->mutex);
936 if (!gclk.hevc_mux_node->ref_count)
937 clk_prepare_enable(gclk.hevc_mux_node->clk);
938
939 gclk.hevc_mux_node->ref_count++;
940 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
941 mutex_unlock(&gclk.hevc_mux_node->mutex);
942
943 pr_debug("the %-15s clock on, ref cnt: %d\n",
944 gclk.hevc_mux_node->name,
945 gclk.hevc_mux_node->ref_count);
946}
947
948static void hevc_clock_off(void)
949{
950 mutex_lock(&gclk.hevc_mux_node->mutex);
951 gclk.hevc_mux_node->ref_count--;
952 if (!gclk.hevc_mux_node->ref_count)
953 clk_disable_unprepare(gclk.hevc_mux_node->clk);
954
955 clock_real_clk[VDEC_HEVC] = 0;
956 mutex_unlock(&gclk.hevc_mux_node->mutex);
957
958 pr_debug("the %-15s clock off, ref cnt: %d\n",
959 gclk.hevc_mux_node->name,
960 gclk.hevc_mux_node->ref_count);
961}
962
963static void hevc_back_clock_on(void)
964{
965 mutex_lock(&gclk.hevc_back_mux_node->mutex);
966 if (!gclk.hevc_back_mux_node->ref_count)
967 clk_prepare_enable(gclk.hevc_back_mux_node->clk);
968
969 gclk.hevc_back_mux_node->ref_count++;
970 WRITE_VREG(DOS_GCLK_EN3, 0xffffffff);
971 mutex_unlock(&gclk.hevc_back_mux_node->mutex);
972
973 pr_debug("the %-15s clock on, ref cnt: %d\n",
974 gclk.hevc_back_mux_node->name,
975 gclk.hevc_back_mux_node->ref_count);
976}
977
978static void hevc_back_clock_off(void)
979{
980 mutex_lock(&gclk.hevc_back_mux_node->mutex);
981 gclk.hevc_back_mux_node->ref_count--;
982 if (!gclk.hevc_back_mux_node->ref_count)
983 clk_disable_unprepare(gclk.hevc_back_mux_node->clk);
984
985 clock_real_clk[VDEC_HEVC] = 0;
986 mutex_unlock(&gclk.hevc_back_mux_node->mutex);
987
988 pr_debug("the %-15s clock off, ref cnt: %d\n",
989 gclk.hevc_back_mux_node->name,
990 gclk.hevc_back_mux_node->ref_count);
991}
992
993static int vdec_clock_get(enum vdec_type_e core)
994{
995 if (core >= VDEC_MAX)
996 return 0;
997
998 return clock_real_clk[core];
999}
1000
1001#define INCLUDE_FROM_ARCH_CLK_MGR
1002
1003/*#define VDEC_HAS_VDEC2*/
1004#define VDEC_HAS_HEVC
1005#define VDEC_HAS_VDEC_HCODEC
1006#define VDEC_HAS_CLK_SETTINGS
1007#define CLK_FOR_CPU {\
1008 AM_MESON_CPU_MAJOR_ID_GXBB,\
1009 AM_MESON_CPU_MAJOR_ID_GXTVBB,\
1010 AM_MESON_CPU_MAJOR_ID_GXL,\
1011 AM_MESON_CPU_MAJOR_ID_GXM,\
1012 AM_MESON_CPU_MAJOR_ID_TXL,\
1013 AM_MESON_CPU_MAJOR_ID_TXLX,\
1014 AM_MESON_CPU_MAJOR_ID_G12A,\
1015 AM_MESON_CPU_MAJOR_ID_G12B,\
1016 AM_MESON_CPU_MAJOR_ID_SM1,\
1017 AM_MESON_CPU_MAJOR_ID_TL1,\
1018 AM_MESON_CPU_MAJOR_ID_TM2,\
1019 0}
1020#include "clk.h"
1021
1022module_param(set_frq_enable, uint, 0664);
1023MODULE_PARM_DESC(set_frq_enable, "\n set frequency enable\n");
1024
1025module_param(vdec_frq, uint, 0664);
1026MODULE_PARM_DESC(vdec_frq, "\n set vdec frequency\n");
1027
1028module_param(hevc_frq, uint, 0664);
1029MODULE_PARM_DESC(hevc_frq, "\n set hevc frequency\n");
1030
1031module_param(hevcb_frq, uint, 0664);
1032MODULE_PARM_DESC(hevcb_frq, "\n set hevcb frequency\n");
1033
1034ARCH_VDEC_CLK_INIT();
1035ARCH_VDEC_CLK_EXIT();
1036
1037MODULE_LICENSE("GPL");
1038