blob: 365a32259d57222506fc1512be8a6379420d2cad [file] [log] [blame]
Googler9398cc32022-12-02 17:21:52 +08001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <linux/types.h>
7#include <linux/init.h>
8#include <linux/module.h>
9#include <linux/kernel.h>
10#include <linux/fs.h>
11#include <linux/device.h>
12#include <linux/cdev.h>
13#include <linux/platform_device.h>
14#include <linux/of.h>
15#include <linux/of_device.h>
16#include <linux/of_fdt.h>
17#include <linux/of_reserved_mem.h>
18#include <linux/of_irq.h>
19#include <linux/string.h>
20#include <linux/mm.h>
21#include <linux/slab.h>
22#include <linux/stat.h>
23#include <linux/errno.h>
24#include <linux/uaccess.h>
25#include <linux/of.h>
26#include <linux/of_device.h>
27#include <linux/ctype.h>
28#include <linux/vmalloc.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <linux/time.h>
32#include <asm/div64.h>
33#include <linux/sched/clock.h>
34
35#include <linux/amlogic/media/vpu/vpu.h>
36#include <linux/amlogic/media/vfm/vframe.h>
37#include <linux/amlogic/media/vfm/vframe_provider.h>
38#include <linux/amlogic/media/vfm/vframe_receiver.h>
39#include <linux/amlogic/media/frame_sync/timestamp.h>
40#include <linux/amlogic/media/frame_sync/tsync.h>
41#include <linux/amlogic/media/vout/vinfo.h>
42#include <linux/amlogic/media/vout/vout_notify.h>
43#include <linux/amlogic/media/frc/frc_reg.h>
44#include <linux/amlogic/media/frc/frc_common.h>
45#include "frc_drv.h"
46#include "frc_proc.h"
47#include "frc_interface.h"
48
49/*
50 * every vsync handle
51 * vf : curret input vf
52 * cur_video_sts: current video state
53 * called in vpp vs ir :vsync_fisr_in
54 * defined(CONFIG_AMLOGIC_MEDIA_FRC)
55 */
56int frc_input_handle(struct vframe_s *vf, struct vpp_frame_par_s *cur_video_sts)
57{
58 struct frc_dev_s *devp = get_frc_devp();
59 u64 timestamp = sched_clock();
60
61 if (!devp)
62 return -1;
63
64 if (!devp->probe_ok || !devp->power_on_flag)
65 return -1;
66
67 /*update vs time*/
68 devp->frc_sts.vs_cnt++;
69 devp->vs_duration = timestamp - devp->vs_timestamp;
70 devp->vs_timestamp = timestamp;
71 frc_vpp_vs_ir_chk_film(devp);
72 /*vframe change detect and video state detects*/
73 frc_input_vframe_handle(devp, vf, cur_video_sts);
74
75 /*frc work mode handle*/
76 // frc_state_handle_old(devp);
77 frc_state_handle(devp);
78 return 0;
79}
80EXPORT_SYMBOL(frc_input_handle);
81
82/*
83 * for other module control frc
84 * FRC_STATE_ENABLE: FRC is working
85 * FRC_STATE_DISABLE: video data input to frc hw module, but frc not works
86 * FRC_STATE_BYPASS: video data not input to frc module
87 *
88 */
89int frc_set_mode(enum frc_state_e state)
90{
91 if (state == FRC_STATE_DISABLE)
92 frc_change_to_state(FRC_STATE_DISABLE);
93 else if (state == FRC_STATE_BYPASS)
94 frc_change_to_state(FRC_STATE_BYPASS);
95 else if (state == FRC_STATE_ENABLE)
96 frc_change_to_state(FRC_STATE_ENABLE);
97
98 return 0;
99}
100
101/*
102 * get current frc video latency
103 * return: ms
104 */
105int frc_get_video_latency(void)
106{
107 struct frc_dev_s *devp = get_frc_devp();
108 // u32 out_frm_dly_num;
109 struct vinfo_s *vinfo = get_current_vinfo();
110 u32 vout_hz = 0;
111 u32 delay_time = 0; /*ms*/
112 u32 delay = 0; /*ms*/
113
114 if (vinfo && vinfo->sync_duration_den != 0)
115 vout_hz = vinfo->sync_duration_num / vinfo->sync_duration_den;
116 // out_frm_dly_num = READ_FRC_BITS(FRC_REG_TOP_CTRL9, 24, 4);
117 if (vout_hz != 0)
118 delay = 35 * 100 / vout_hz;
119 // delay_time = out_frm_dly_num;
120 if (!devp || !vinfo)
121 return 0;
122 if (devp->frc_sts.auto_ctrl == 1) {
123 // if (devp->in_sts.vf_sts == VFRAME_NO)
124 // delay_time = delay;
125 // else if (devp->frc_sts.state == FRC_STATE_BYPASS ||
126 // devp->frc_sts.state == FRC_STATE_DISABLE)
127 // delay_time = 0;
128 // else if (devp->frc_sts.state == FRC_STATE_ENABLE)
129 // delay_time = delay;
130 delay_time = delay;
131 } else {
132 delay_time = 0;
133 }
134 return delay_time;
135}
136EXPORT_SYMBOL(frc_get_video_latency);
137
138int frc_is_on(void)
139{
140 struct frc_dev_s *devp = get_frc_devp();
141
142 if (!devp)
143 return 0;
144
145 if (!devp->probe_ok || !devp->power_on_flag)
146 return 0;
147
148 if (READ_FRC_BITS(FRC_TOP_CTRL, 0, 1) == FRC_STATE_ENABLE)
149 return 1;
150
151 return 0;
152}
153EXPORT_SYMBOL(frc_is_on);
154
155int frc_is_supported(void)
156{
157 struct frc_dev_s *devp = get_frc_devp();
158
159 if (!devp)
160 return 0;
161 if (!devp->probe_ok)
162 return 0;
163
164 return 1;
165}
166EXPORT_SYMBOL(frc_is_supported);
167
168int frc_set_seg_display(u8 enable, u8 seg1, u8 seg2, u8 seg3)
169{
170 struct frc_dev_s *devp = get_frc_devp();
171
172 if (!devp)
173 return 0;
174 if (!devp->probe_ok)
175 return 0;
176 if (enable) {
177 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_POSI_AND_NUM41_NUM42, 0xE1 << 24, 0xFF000000);
178 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 1 << 31, BIT_31);
179 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 1 << 23, BIT_23);
180 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 1 << 15, BIT_15);
181 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 2 << 28, 0x70000000);
182 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 1 << 20, 0x700000);
183 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 2 << 12, 0x7000);
184 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46,
185 seg1 << 24, 0xF000000);
186 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, seg2 << 16, 0xF0000);
187 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, seg3 << 8, 0xF00);
188 } else {
189 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 0, BIT_31);
190 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 0, BIT_23);
191 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_NUM43_NUM44_NUM45_NUM46, 0, BIT_15);
192 UPDATE_FRC_REG_BITS(FRC_MC_SEVEN_FLAG_POSI_AND_NUM41_NUM42, 0x03 << 24, 0xFF000000);
193 }
194 return 1;
195}
196EXPORT_SYMBOL(frc_set_seg_display);