video.c 89 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086
  1. /*
  2. * AMLOGIC Audio/Video streaming port driver.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the named License,
  7. * or any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  17. *
  18. * Author: Tim Yao <timyao@amlogic.com>
  19. *
  20. */
  21. #include <linux/version.h>
  22. #include <linux/kernel.h>
  23. #include <linux/module.h>
  24. #include <linux/spinlock.h>
  25. #include <linux/interrupt.h>
  26. #include <linux/fs.h>
  27. #include <mach/am_regs.h>
  28. #include <linux/string.h>
  29. #include <linux/io.h>
  30. #include <linux/mm.h>
  31. #include <linux/major.h>
  32. #include <linux/err.h>
  33. #include <linux/mutex.h>
  34. #include <linux/platform_device.h>
  35. #include <linux/ctype.h>
  36. #include <linux/amports/ptsserv.h>
  37. #include <linux/amports/timestamp.h>
  38. #include <linux/amports/tsync.h>
  39. #include <linux/amports/canvas.h>
  40. #include <linux/amports/vframe.h>
  41. #include <linux/amports/vframe_provider.h>
  42. #include <linux/amports/vframe_receiver.h>
  43. #include <linux/amports/amstream.h>
  44. #include <linux/vout/vout_notify.h>
  45. #include <linux/sched.h>
  46. #include <linux/poll.h>
  47. #include <linux/clk.h>
  48. #include <linux/logo/logo.h>
  49. #ifdef CONFIG_PM
  50. #include <linux/delay.h>
  51. #include <linux/pm.h>
  52. #endif
  53. #include <plat/fiq_bridge.h>
  54. #include <asm/fiq.h>
  55. #include <asm/uaccess.h>
  56. #include "videolog.h"
  57. #ifdef CONFIG_AM_VIDEO_LOG
  58. #define AMLOG
  59. #endif
  60. #include <linux/amlog.h>
  61. MODULE_AMLOG(LOG_LEVEL_ERROR, 0, LOG_DEFAULT_LEVEL_DESC, LOG_MASK_DESC);
  62. #include "video.h"
  63. #include "vpp.h"
  64. #ifdef CONFIG_AM_DEINTERLACE
  65. #include "deinterlace.h"
  66. #endif
  67. #include "linux/amports/ve.h"
  68. #include "linux/amports/cm.h"
  69. #include "ve_regs.h"
  70. #include "amve.h"
  71. #include "cm_regs.h"
  72. #include "amcm.h"
  73. static int debugflags=0;
  74. #define DEBUG_FLAG_FFPLAY (1<<0)
  75. #define DEBUG_FLAG_CALC_PTS_INC (1<<1)
  76. #define RECEIVER_NAME "amvideo"
  77. static int video_receiver_event_fun(int type, void* data, void*);
  78. static const struct vframe_receiver_op_s video_vf_receiver =
  79. {
  80. .event_cb = video_receiver_event_fun
  81. };
  82. static struct vframe_receiver_s video_vf_recv;
  83. #define RECEIVER4OSD_NAME "amvideo4osd"
  84. static int video4osd_receiver_event_fun(int type, void* data, void*);
  85. static const struct vframe_receiver_op_s video4osd_vf_receiver =
  86. {
  87. .event_cb = video4osd_receiver_event_fun
  88. };
  89. static struct vframe_receiver_s video4osd_vf_recv;
  90. static struct vframe_provider_s * osd_prov = NULL;
  91. #define DRIVER_NAME "amvideo"
  92. #define MODULE_NAME "amvideo"
  93. #define DEVICE_NAME "amvideo"
  94. //#define FIQ_VSYNC
  95. //#define SLOW_SYNC_REPEAT
  96. //#define INTERLACE_FIELD_MATCH_PROCESS
  97. #ifdef FIQ_VSYNC
  98. #define BRIDGE_IRQ INT_TIMER_D
  99. #define BRIDGE_IRQ_SET() WRITE_CBUS_REG(ISA_TIMERD, 1)
  100. #endif
  101. #define RESERVE_CLR_FRAME
  102. #define EnableVideoLayer() \
  103. do { SET_MPEG_REG_MASK(VPP_MISC, \
  104. VPP_VD1_PREBLEND | VPP_PREBLEND_EN | VPP_VD1_POSTBLEND); \
  105. } while (0)
  106. #define EnableVideoLayer2() \
  107. do { SET_MPEG_REG_MASK(VPP_MISC, \
  108. VPP_VD2_PREBLEND | (0x1ff << VPP_VD2_ALPHA_BIT)); \
  109. } while (0)
  110. #define DisableVideoLayer() \
  111. do { CLEAR_MPEG_REG_MASK(VPP_MISC, \
  112. VPP_VD1_PREBLEND|VPP_VD2_PREBLEND|VPP_VD2_POSTBLEND|VPP_VD1_POSTBLEND ); \
  113. } while (0)
  114. #define DisableVideoLayer_PREBELEND() \
  115. do { CLEAR_MPEG_REG_MASK(VPP_MISC, \
  116. VPP_VD1_PREBLEND|VPP_VD2_PREBLEND); \
  117. } while (0)
  118. /*********************************************************/
  119. #define VOUT_TYPE_TOP_FIELD 0
  120. #define VOUT_TYPE_BOT_FIELD 1
  121. #define VOUT_TYPE_PROG 2
  122. #define VIDEO_DISABLE_NONE 0
  123. #define VIDEO_DISABLE_NORMAL 1
  124. #define VIDEO_DISABLE_FORNEXT 2
  125. #define MAX_ZOOM_RATIO 300
  126. #define DUR2PTS(x) ((x) - ((x) >> 4))
  127. #define DUR2PTS_RM(x) ((x) & 0xf)
  128. #ifdef VIDEO_PTS_CHASE
  129. static int vpts_chase=0;
  130. static int av_sync_flag=0;
  131. static int vpts_chase_counter;
  132. static int vpts_chase_pts_diff;
  133. #endif
  134. #define DEBUG_FLAG_BLACKOUT 0x1
  135. #define DEBUG_FLAG_TOGGLE_FRAME 0x2
  136. #define DEBUG_FLAG_TOGGLE_SKIP_KEEP_CURRENT 0x10000
  137. static int debug_flag = DEBUG_FLAG_BLACKOUT;
  138. const char video_dev_id[] = "amvideo-dev";
  139. #ifdef CONFIG_PM
  140. typedef struct {
  141. int event;
  142. u32 vpp_misc;
  143. } video_pm_state_t;
  144. static video_pm_state_t pm_state;
  145. #endif
  146. static DEFINE_MUTEX(video_module_mutex);
  147. static DEFINE_SPINLOCK(lock);
  148. static u32 frame_par_ready_to_set, frame_par_force_to_set;
  149. static u32 vpts_remainder;
  150. static bool video_property_changed = false;
  151. static u32 video_notify_flag = 0;
  152. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  153. static u32 video_scaler_mode = 0;
  154. static int content_top = 0, content_left = 0, content_w = 0, content_h = 0;
  155. static int scaler_pos_changed = 0;
  156. #endif
  157. #ifdef CONFIG_AM_VIDEO2
  158. void set_clone_frame_rate(unsigned int frame_rate, unsigned int delay);
  159. #endif
  160. int video_property_notify(int flag)
  161. {
  162. video_property_changed = flag;
  163. return 0;
  164. }
  165. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  166. int video_scaler_notify(int flag)
  167. {
  168. video_scaler_mode = flag;
  169. video_property_changed = true;
  170. return 0;
  171. }
  172. u32 amvideo_get_scaler_para(int* x, int* y, int* w, int* h, u32* ratio)
  173. {
  174. *x = content_left;
  175. *y = content_top;
  176. *w = content_w;
  177. *h = content_h;
  178. //*ratio = 100;
  179. return video_scaler_mode;
  180. }
  181. void amvideo_set_scaler_para(int x, int y, int w, int h,int flag)
  182. {
  183. mutex_lock(&video_module_mutex);
  184. if(w < 2)
  185. w = 0;
  186. if(h < 2)
  187. h = 0;
  188. if(flag){
  189. if((content_left!=x)||(content_top!=y)||(content_w!=w)||(content_h!=h))
  190. scaler_pos_changed = 1;
  191. content_left = x;
  192. content_top = y;
  193. content_w = w;
  194. content_h = h;
  195. }else{
  196. vpp_set_video_layer_position(x, y, w, h);
  197. }
  198. video_property_changed = true;
  199. mutex_unlock(&video_module_mutex);
  200. return;
  201. }
  202. u32 amvideo_get_scaler_mode(void)
  203. {
  204. return video_scaler_mode;
  205. }
  206. #endif
  207. /* display canvas */
  208. static u32 disp_canvas_index[6] = {
  209. DISPLAY_CANVAS_BASE_INDEX,
  210. DISPLAY_CANVAS_BASE_INDEX + 1,
  211. DISPLAY_CANVAS_BASE_INDEX + 2,
  212. DISPLAY_CANVAS_BASE_INDEX + 3,
  213. DISPLAY_CANVAS_BASE_INDEX + 4,
  214. DISPLAY_CANVAS_BASE_INDEX + 5,
  215. };
  216. static u32 disp_canvas[2];
  217. static u32 post_canvas = 0;
  218. static ulong keep_y_addr = 0, *keep_y_addr_remap = NULL;
  219. static ulong keep_u_addr = 0, *keep_u_addr_remap = NULL;
  220. static ulong keep_v_addr = 0, *keep_v_addr_remap = NULL;
  221. #define Y_BUFFER_SIZE 0x400000 // for 1920*1088
  222. #define U_BUFFER_SIZE 0x100000 //compatible with NV21
  223. #define V_BUFFER_SIZE 0x80000
  224. /* zoom information */
  225. static u32 zoom_start_x_lines;
  226. static u32 zoom_end_x_lines;
  227. static u32 zoom_start_y_lines;
  228. static u32 zoom_end_y_lines;
  229. /* wide settings */
  230. static u32 wide_setting;
  231. /* black out policy */
  232. #if defined(CONFIG_JPEGLOGO)
  233. static u32 blackout = 0;
  234. #else
  235. static u32 blackout = 1;
  236. #endif
  237. static u32 force_blackout = 0;
  238. /* disable video */
  239. static u32 disable_video = VIDEO_DISABLE_NONE;
  240. #ifdef SLOW_SYNC_REPEAT
  241. /* video frame repeat count */
  242. static u32 frame_repeat_count = 0;
  243. #endif
  244. /* vout */
  245. static const vinfo_t *vinfo = NULL;
  246. /* config */
  247. static vframe_t *cur_dispbuf = NULL;
  248. static vframe_t vf_local;
  249. static u32 vsync_pts_inc;
  250. /* frame rate calculate */
  251. static u32 last_frame_count = 0;
  252. static u32 frame_count = 0;
  253. static u32 last_frame_time = 0;
  254. static u32 timer_count =0 ;
  255. static u32 vsync_count =0 ;
  256. static vpp_frame_par_t *cur_frame_par, *next_frame_par;
  257. static vpp_frame_par_t frame_parms[2];
  258. /* vsync pass flag */
  259. static u32 wait_sync;
  260. #ifdef FIQ_VSYNC
  261. static bridge_item_t vsync_fiq_bridge;
  262. #endif
  263. /* trickmode i frame*/
  264. u32 trickmode_i = 0;
  265. /* trickmode ff/fb */
  266. u32 trickmode_fffb = 0;
  267. atomic_t trickmode_framedone = ATOMIC_INIT(0);
  268. atomic_t video_unreg_flag = ATOMIC_INIT(0);
  269. /* last_playback_filename */
  270. char file_name[512];
  271. static const f2v_vphase_type_t vpp_phase_table[4][3] = {
  272. {F2V_P2IT, F2V_P2IB, F2V_P2P }, /* VIDTYPE_PROGRESSIVE */
  273. {F2V_IT2IT, F2V_IT2IB, F2V_IT2P}, /* VIDTYPE_INTERLACE_TOP */
  274. {F2V_P2IT, F2V_P2IB, F2V_P2P },
  275. {F2V_IB2IT, F2V_IB2IB, F2V_IB2P} /* VIDTYPE_INTERLACE_BOTTOM */
  276. };
  277. static const u8 skip_tab[6] = { 0x24, 0x04, 0x68, 0x48, 0x28, 0x08 };
  278. /* wait queue for poll */
  279. static wait_queue_head_t amvideo_trick_wait;
  280. #if 0
  281. /* video enhancement */
  282. static struct ve_bext_s ve_bext;
  283. static struct ve_dnlp_s ve_dnlp;
  284. static struct ve_hsvs_s ve_hsvs;
  285. static struct ve_ccor_s ve_ccor;
  286. static struct ve_benh_s ve_demo;
  287. static struct ve_demo_s ve_demo;
  288. typedef struct ve_regs_s {
  289. unsigned val : 32;
  290. unsigned reg : 14;
  291. unsigned port : 2; // port port_addr port_data remark
  292. // 0 NA NA direct access
  293. // 1 VPP_CHROMA_ADDR_PORT VPP_CHROMA_DATA_PORT CM port registers
  294. // 2 NA NA reserved
  295. // 3 NA NA reserved
  296. unsigned bit : 5;
  297. unsigned wid : 5;
  298. unsigned mode : 1; // 0:read, 1:write
  299. unsigned rsv : 5;
  300. } ve_regs_t;
  301. static uchar ve_dnlp_tgt[64], ve_dnlp_rt;
  302. static ulong ve_dnlp_lpf[64], ve_dnlp_reg[16];
  303. static ulong ve_benh_ve_benh_inv[32][2] = { // [0]: inv_10_0, [1]: inv_11
  304. {2047, 1}, {2047, 1}, { 0, 1}, {1365, 0}, {1024, 0}, { 819, 0}, { 683, 0}, { 585, 0},
  305. { 512, 0}, { 455, 0}, { 410, 0}, { 372, 0}, { 341, 0}, { 315, 0}, { 293, 0}, { 273, 0},
  306. { 256, 0}, { 241, 0}, { 228, 0}, { 216, 0}, { 205, 0}, { 195, 0}, { 186, 0}, { 178, 0},
  307. { 171, 0}, { 164, 0}, { 158, 0}, { 152, 0}, { 146, 0}, { 141, 0}, { 137, 0}, { 132, 0},
  308. };
  309. static ulong ve_reg_limit(ulong val, ulong wid)
  310. {
  311. if (val < (1 << wid)) {
  312. return(val);
  313. } else {
  314. return((1 << wid) - 1);
  315. }
  316. }
  317. #endif
  318. /*********************************************************/
  319. static inline vframe_t *video_vf_peek(void)
  320. {
  321. #ifdef CONFIG_AM_DEINTERLACE
  322. int deinterlace_mode = get_deinterlace_mode();
  323. if (deinterlace_mode == 2) {
  324. int di_pre_recycle_buf = get_di_pre_recycle_buf();
  325. if (di_pre_recycle_buf == 1) {
  326. return peek_di_out_buf();
  327. } else if (di_pre_recycle_buf == 0) {
  328. return vf_peek(RECEIVER_NAME);
  329. }
  330. } else {
  331. return vf_peek(RECEIVER_NAME);
  332. }
  333. return NULL;
  334. #else
  335. return vf_peek(RECEIVER_NAME);
  336. #endif
  337. }
  338. static inline vframe_t *video_vf_get(void)
  339. {
  340. vframe_t *vf = NULL;
  341. #ifdef CONFIG_AM_DEINTERLACE
  342. int deinterlace_mode = get_deinterlace_mode();
  343. if (deinterlace_mode == 2) {
  344. int di_pre_recycle_buf = get_di_pre_recycle_buf();
  345. if (di_pre_recycle_buf == 1) {
  346. vframe_t *disp_buf = peek_di_out_buf();
  347. if (disp_buf) {
  348. set_post_di_mem(disp_buf->blend_mode);
  349. inc_field_counter();
  350. }
  351. return disp_buf;
  352. } else if (di_pre_recycle_buf == 0) {
  353. vf = vf_get(RECEIVER_NAME);
  354. if (vf) video_notify_flag |= VIDEO_NOTIFY_PROVIDER_GET;
  355. return vf;
  356. }
  357. } else {
  358. vf = vf_get(RECEIVER_NAME);
  359. if (vf) video_notify_flag |= VIDEO_NOTIFY_PROVIDER_GET;
  360. return vf;
  361. }
  362. return NULL;
  363. #else
  364. vf = vf_get(RECEIVER_NAME);
  365. if (vf) video_notify_flag |= VIDEO_NOTIFY_PROVIDER_GET;
  366. return vf;
  367. #endif
  368. }
  369. static int vf_get_states(vframe_states_t *states)
  370. {
  371. int ret = -1;
  372. unsigned long flags;
  373. struct vframe_provider_s *vfp;
  374. vfp = vf_get_provider(RECEIVER_NAME);
  375. spin_lock_irqsave(&lock, flags);
  376. if (vfp && vfp->ops && vfp->ops->vf_states) {
  377. ret=vfp->ops->vf_states(states, vfp->op_arg);
  378. }
  379. spin_unlock_irqrestore(&lock, flags);
  380. return ret;
  381. }
  382. static inline void video_vf_put(vframe_t *vf)
  383. {
  384. struct vframe_provider_s *vfp = vf_get_provider(RECEIVER_NAME);
  385. #ifdef CONFIG_AM_DEINTERLACE
  386. int deinterlace_mode = get_deinterlace_mode();
  387. if (deinterlace_mode == 2) {
  388. int di_pre_recycle_buf = get_di_pre_recycle_buf();
  389. if (di_pre_recycle_buf == 0) {
  390. if (vfp) {
  391. vf_put(vf, RECEIVER_NAME);
  392. video_notify_flag |= VIDEO_NOTIFY_PROVIDER_PUT;
  393. }
  394. }
  395. } else {
  396. if (vfp) {
  397. vf_put(vf, RECEIVER_NAME);
  398. video_notify_flag |= VIDEO_NOTIFY_PROVIDER_PUT;
  399. }
  400. }
  401. #else
  402. if (vfp) {
  403. vf_put(vf, RECEIVER_NAME);
  404. video_notify_flag |= VIDEO_NOTIFY_PROVIDER_PUT;
  405. }
  406. #endif
  407. }
  408. static void vpp_settings_h(vpp_frame_par_t *framePtr)
  409. {
  410. vppfilter_mode_t *vpp_filter = &framePtr->vpp_filter;
  411. u32 r1, r2, r3;
  412. r1 = framePtr->VPP_hsc_linear_startp - framePtr->VPP_hsc_startp;
  413. r2 = framePtr->VPP_hsc_linear_endp - framePtr->VPP_hsc_startp;
  414. r3 = framePtr->VPP_hsc_endp - framePtr->VPP_hsc_startp;
  415. WRITE_MPEG_REG(VPP_POSTBLEND_VD1_H_START_END,
  416. ((framePtr->VPP_hsc_startp & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  417. ((framePtr->VPP_hsc_endp & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  418. WRITE_MPEG_REG(VPP_BLEND_VD2_H_START_END,
  419. ((framePtr->VPP_hsc_startp & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  420. ((framePtr->VPP_hsc_endp & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  421. WRITE_MPEG_REG(VPP_HSC_REGION12_STARTP,
  422. (0 << VPP_REGION1_BIT) |
  423. ((r1 & VPP_REGION_MASK) << VPP_REGION2_BIT));
  424. WRITE_MPEG_REG(VPP_HSC_REGION34_STARTP,
  425. ((r2 & VPP_REGION_MASK) << VPP_REGION3_BIT) |
  426. ((r3 & VPP_REGION_MASK) << VPP_REGION4_BIT));
  427. WRITE_MPEG_REG(VPP_HSC_REGION4_ENDP, r3);
  428. WRITE_MPEG_REG(VPP_HSC_START_PHASE_STEP,
  429. vpp_filter->vpp_hf_start_phase_step);
  430. WRITE_MPEG_REG(VPP_LINE_IN_LENGTH, framePtr->VPP_line_in_length_);
  431. WRITE_MPEG_REG(VPP_PREBLEND_H_SIZE, framePtr->VPP_line_in_length_);
  432. }
  433. static void vpp_settings_v(vpp_frame_par_t *framePtr)
  434. {
  435. vppfilter_mode_t *vpp_filter = &framePtr->vpp_filter;
  436. u32 r;
  437. r = framePtr->VPP_vsc_endp - framePtr->VPP_vsc_startp;
  438. WRITE_MPEG_REG(VPP_POSTBLEND_VD1_V_START_END,
  439. ((framePtr->VPP_vsc_startp & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  440. ((framePtr->VPP_vsc_endp & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  441. WRITE_MPEG_REG(VPP_BLEND_VD2_V_START_END,
  442. (((framePtr->VPP_vsc_endp / 2) & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  443. (((framePtr->VPP_vsc_endp) & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  444. WRITE_MPEG_REG(VPP_VSC_REGION12_STARTP, 0);
  445. WRITE_MPEG_REG(VPP_VSC_REGION34_STARTP,
  446. ((r & VPP_REGION_MASK) << VPP_REGION3_BIT) |
  447. ((r & VPP_REGION_MASK) << VPP_REGION4_BIT));
  448. WRITE_MPEG_REG(VPP_VSC_REGION4_ENDP, r);
  449. WRITE_MPEG_REG(VPP_VSC_START_PHASE_STEP,
  450. vpp_filter->vpp_vsc_start_phase_step);
  451. }
  452. static void zoom_display_horz(void)
  453. {
  454. WRITE_MPEG_REG(VD1_IF0_LUMA_X0,
  455. (zoom_start_x_lines << VDIF_PIC_START_BIT) |
  456. (zoom_end_x_lines << VDIF_PIC_END_BIT));
  457. WRITE_MPEG_REG(VD1_IF0_CHROMA_X0,
  458. (zoom_start_x_lines / 2 << VDIF_PIC_START_BIT) |
  459. (zoom_end_x_lines / 2 << VDIF_PIC_END_BIT));
  460. WRITE_MPEG_REG(VD1_IF0_LUMA_X1,
  461. (zoom_start_x_lines << VDIF_PIC_START_BIT) |
  462. (zoom_end_x_lines << VDIF_PIC_END_BIT));
  463. WRITE_MPEG_REG(VD1_IF0_CHROMA_X1,
  464. (zoom_start_x_lines / 2 << VDIF_PIC_START_BIT) |
  465. (zoom_end_x_lines / 2 << VDIF_PIC_END_BIT));
  466. WRITE_MPEG_REG(VIU_VD1_FMT_W,
  467. ((zoom_end_x_lines - zoom_start_x_lines + 1) << VD1_FMT_LUMA_WIDTH_BIT) |
  468. ((zoom_end_x_lines / 2 - zoom_start_x_lines / 2 + 1) << VD1_FMT_CHROMA_WIDTH_BIT));
  469. WRITE_MPEG_REG(VD2_IF0_LUMA_X0,
  470. (zoom_start_x_lines << VDIF_PIC_START_BIT) |
  471. (zoom_end_x_lines << VDIF_PIC_END_BIT));
  472. WRITE_MPEG_REG(VD2_IF0_CHROMA_X0,
  473. (zoom_start_x_lines / 2 << VDIF_PIC_START_BIT) |
  474. (zoom_end_x_lines / 2 << VDIF_PIC_END_BIT));
  475. WRITE_MPEG_REG(VD2_IF0_LUMA_X1,
  476. (zoom_start_x_lines << VDIF_PIC_START_BIT) |
  477. (zoom_end_x_lines << VDIF_PIC_END_BIT));
  478. WRITE_MPEG_REG(VD2_IF0_CHROMA_X1,
  479. (zoom_start_x_lines / 2 << VDIF_PIC_START_BIT) |
  480. (zoom_end_x_lines / 2 << VDIF_PIC_END_BIT));
  481. WRITE_MPEG_REG(VIU_VD2_FMT_W,
  482. ((zoom_end_x_lines - zoom_start_x_lines + 1) << VD1_FMT_LUMA_WIDTH_BIT) |
  483. ((zoom_end_x_lines / 2 - zoom_start_x_lines / 2 + 1) << VD1_FMT_CHROMA_WIDTH_BIT));
  484. }
  485. static void zoom_display_vert(void)
  486. {
  487. if ((cur_dispbuf) && (cur_dispbuf->type & VIDTYPE_MVC)) {
  488. WRITE_MPEG_REG(VD1_IF0_LUMA_Y0,
  489. (zoom_start_y_lines * 2 << VDIF_PIC_START_BIT) |
  490. (zoom_end_y_lines * 2 << VDIF_PIC_END_BIT));
  491. WRITE_MPEG_REG(VD1_IF0_CHROMA_Y0,
  492. ((zoom_start_y_lines) << VDIF_PIC_START_BIT) |
  493. ((zoom_end_y_lines) << VDIF_PIC_END_BIT));
  494. WRITE_MPEG_REG(VD2_IF0_LUMA_Y0,
  495. (zoom_start_y_lines * 2 << VDIF_PIC_START_BIT) |
  496. (zoom_end_y_lines * 2 << VDIF_PIC_END_BIT));
  497. WRITE_MPEG_REG(VD2_IF0_CHROMA_Y0,
  498. ((zoom_start_y_lines) << VDIF_PIC_START_BIT) |
  499. ((zoom_end_y_lines) << VDIF_PIC_END_BIT));
  500. } else {
  501. WRITE_MPEG_REG(VD1_IF0_LUMA_Y0,
  502. (zoom_start_y_lines << VDIF_PIC_START_BIT) |
  503. (zoom_end_y_lines << VDIF_PIC_END_BIT));
  504. WRITE_MPEG_REG(VD1_IF0_CHROMA_Y0,
  505. ((zoom_start_y_lines / 2) << VDIF_PIC_START_BIT) |
  506. ((zoom_end_y_lines / 2) << VDIF_PIC_END_BIT));
  507. WRITE_MPEG_REG(VD1_IF0_LUMA_Y1,
  508. (zoom_start_y_lines << VDIF_PIC_START_BIT) |
  509. (zoom_end_y_lines << VDIF_PIC_END_BIT));
  510. WRITE_MPEG_REG(VD1_IF0_CHROMA_Y1,
  511. ((zoom_start_y_lines / 2) << VDIF_PIC_START_BIT) |
  512. ((zoom_end_y_lines / 2) << VDIF_PIC_END_BIT));
  513. }
  514. }
  515. static void vsync_toggle_frame(vframe_t *vf)
  516. {
  517. u32 first_picture = 0;
  518. frame_count++;
  519. #ifdef CONFIG_AM_DEINTERLACE
  520. int deinterlace_mode = get_deinterlace_mode();
  521. #endif
  522. if(vf->early_process_fun){
  523. if(vf->early_process_fun(vf->private_data) == 1){
  524. video_property_changed = true;
  525. }
  526. }
  527. else{
  528. #ifndef CONFIG_AM_DEINTERLACE
  529. if(READ_MPEG_REG(DI_IF1_GEN_REG)&0x1){
  530. //disable post di
  531. WRITE_MPEG_REG(DI_POST_CTRL, 0x3 << 30);
  532. WRITE_MPEG_REG(DI_POST_SIZE, (32-1) | ((128-1) << 16));
  533. WRITE_MPEG_REG(DI_IF1_GEN_REG, READ_MPEG_REG(DI_IF1_GEN_REG) & 0xfffffffe);
  534. }
  535. #endif
  536. }
  537. timer_count = 0 ;
  538. if ((vf->width == 0) && (vf->height == 0)) {
  539. amlog_level(LOG_LEVEL_ERROR, "Video: invalid frame dimension\n");
  540. return;
  541. }
  542. if ((cur_dispbuf) && (cur_dispbuf != &vf_local) && (cur_dispbuf != vf)
  543. &&(video_property_changed != 2)) {
  544. if(cur_dispbuf->source_type == VFRAME_SOURCE_TYPE_OSD){
  545. if (osd_prov && osd_prov->ops && osd_prov->ops->put){
  546. osd_prov->ops->put(cur_dispbuf, osd_prov->op_arg);
  547. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  548. printk("[video4osd] pre vframe is osd_vframe, put it\n");
  549. }
  550. }
  551. first_picture = 1;
  552. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  553. printk("[video4osd] pre vframe is osd_vframe, clear it to NULL\n");
  554. }
  555. }
  556. else{
  557. video_vf_put(cur_dispbuf);
  558. }
  559. } else {
  560. first_picture = 1;
  561. }
  562. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  563. if(first_picture){
  564. printk("[video4osd] first %s picture {%d,%d}\n", (vf->source_type==VFRAME_SOURCE_TYPE_OSD)?"OSD":"", vf->width, vf->height);
  565. }
  566. }
  567. if (video_property_changed) {
  568. video_property_changed = false;
  569. first_picture = 1;
  570. }
  571. /* switch buffer */
  572. post_canvas = vf->canvas0Addr;
  573. canvas_copy(vf->canvas0Addr & 0xff, disp_canvas_index[0]);
  574. canvas_copy((vf->canvas0Addr >> 8) & 0xff, disp_canvas_index[1]);
  575. canvas_copy((vf->canvas0Addr >> 16) & 0xff, disp_canvas_index[2]);
  576. canvas_copy(vf->canvas1Addr & 0xff, disp_canvas_index[3]);
  577. canvas_copy((vf->canvas1Addr >> 8) & 0xff, disp_canvas_index[4]);
  578. canvas_copy((vf->canvas1Addr >> 16) & 0xff, disp_canvas_index[5]);
  579. WRITE_MPEG_REG(VD1_IF0_CANVAS0, disp_canvas[0]);
  580. WRITE_MPEG_REG(VD1_IF0_CANVAS1, disp_canvas[1]);
  581. WRITE_MPEG_REG(VD2_IF0_CANVAS0, disp_canvas[1]);
  582. WRITE_MPEG_REG(VD2_IF0_CANVAS1, disp_canvas[1]);
  583. /* set video PTS */
  584. if (cur_dispbuf != vf) {
  585. if(vf->source_type != VFRAME_SOURCE_TYPE_OSD){
  586. if (vf->pts != 0) {
  587. amlog_mask(LOG_MASK_TIMESTAMP,
  588. "vpts to vf->pts: 0x%x, scr: 0x%x, abs_scr: 0x%x\n",
  589. vf->pts, timestamp_pcrscr_get(), READ_MPEG_REG(SCR_HIU));
  590. timestamp_vpts_set(vf->pts);
  591. } else if (cur_dispbuf) {
  592. amlog_mask(LOG_MASK_TIMESTAMP,
  593. "vpts inc: 0x%x, scr: 0x%x, abs_scr: 0x%x\n",
  594. timestamp_vpts_get() + DUR2PTS(cur_dispbuf->duration),
  595. timestamp_pcrscr_get(), READ_MPEG_REG(SCR_HIU));
  596. timestamp_vpts_inc(DUR2PTS(cur_dispbuf->duration));
  597. vpts_remainder += DUR2PTS_RM(cur_dispbuf->duration);
  598. if (vpts_remainder >= 0xf) {
  599. vpts_remainder -= 0xf;
  600. timestamp_vpts_inc(-1);
  601. }
  602. }
  603. }
  604. else{
  605. first_picture = 1;
  606. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  607. printk("[video4osd] cur vframe is osd_vframe, do not set PTS\n");
  608. }
  609. }
  610. vf->type_backup = vf->type;
  611. }
  612. /* enable new config on the new frames */
  613. if ((first_picture) ||
  614. (cur_dispbuf->bufWidth != vf->bufWidth) ||
  615. (cur_dispbuf->width != vf->width) ||
  616. (cur_dispbuf->height != vf->height) ||
  617. (cur_dispbuf->ratio_control != vf->ratio_control) ||
  618. ((cur_dispbuf->type_backup & VIDTYPE_INTERLACE) !=
  619. (vf->type_backup & VIDTYPE_INTERLACE))) {
  620. amlog_mask(LOG_MASK_FRAMEINFO,
  621. "%s %dx%d ar=0x%x\n",
  622. ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) ?
  623. "interlace-top" :
  624. ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_BOTTOM) ?
  625. "interlace-bottom" :
  626. "progressive",
  627. vf->width,
  628. vf->height,
  629. vf->ratio_control);
  630. next_frame_par = (&frame_parms[0] == next_frame_par) ?
  631. &frame_parms[1] : &frame_parms[0];
  632. #ifdef CONFIG_AM_DEINTERLACE
  633. if ((deinterlace_mode != 0)
  634. && (vf->type & VIDTYPE_INTERLACE)
  635. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  636. && (vf->width <= 720)
  637. #endif
  638. ) {
  639. vf->type &= ~VIDTYPE_TYPEMASK;
  640. if (deinterlace_mode == 1) {
  641. vf->type |= VIDTYPE_VIU_FIELD;
  642. inc_field_counter();
  643. }
  644. }
  645. #endif
  646. vpp_set_filters(wide_setting, vf, next_frame_par, vinfo);
  647. /* apply new vpp settings */
  648. frame_par_ready_to_set = 1;
  649. } else {
  650. #ifdef CONFIG_AM_DEINTERLACE
  651. if ((deinterlace_mode != 0)
  652. && (vf->type & VIDTYPE_INTERLACE)
  653. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  654. && (vf->width <= 720)
  655. #endif
  656. ) {
  657. vf->type &= ~VIDTYPE_TYPEMASK;
  658. if (deinterlace_mode == 1) {
  659. vf->type |= VIDTYPE_VIU_FIELD;
  660. inc_field_counter();
  661. }
  662. }
  663. #endif
  664. }
  665. cur_dispbuf = vf;
  666. if ((vf->type & VIDTYPE_NO_VIDEO_ENABLE) == 0) {
  667. if (disable_video == VIDEO_DISABLE_FORNEXT) {
  668. EnableVideoLayer();
  669. disable_video = VIDEO_DISABLE_NONE;
  670. }
  671. if (first_picture && (disable_video != VIDEO_DISABLE_NORMAL)) {
  672. EnableVideoLayer();
  673. if (cur_dispbuf->type & VIDTYPE_MVC)
  674. EnableVideoLayer2();
  675. }
  676. }
  677. if (first_picture) {
  678. frame_par_ready_to_set = 1;
  679. #ifdef CONFIG_AM_DEINTERLACE
  680. if (deinterlace_mode != 2) {
  681. disable_deinterlace();
  682. } else {
  683. disable_post_deinterlace();
  684. }
  685. #endif
  686. #ifdef VIDEO_PTS_CHASE
  687. av_sync_flag=0;
  688. #endif
  689. }
  690. }
  691. static void viu_set_dcu(vpp_frame_par_t *frame_par, vframe_t *vf)
  692. {
  693. u32 r;
  694. u32 vphase, vini_phase;
  695. u32 pat, loop;
  696. static const u32 vpat[] = {0, 0x8, 0x9, 0xa, 0xb, 0xc};
  697. r = (3 << VDIF_URGENT_BIT) |
  698. (17 << VDIF_HOLD_LINES_BIT) |
  699. VDIF_FORMAT_SPLIT |
  700. VDIF_CHRO_RPT_LAST |
  701. VDIF_ENABLE |
  702. VDIF_RESET_ON_GO_FIELD;
  703. if ((vf->type & VIDTYPE_VIU_SINGLE_PLANE) == 0) {
  704. r |= VDIF_SEPARATE_EN;
  705. } else {
  706. if (vf->type & VIDTYPE_VIU_422) {
  707. r |= VDIF_FORMAT_422;
  708. } else {
  709. r |= VDIF_FORMAT_RGB888_YUV444 | VDIF_DEMUX_MODE_RGB_444;
  710. }
  711. }
  712. WRITE_MPEG_REG(VD1_IF0_GEN_REG, r);
  713. WRITE_MPEG_REG(VD2_IF0_GEN_REG, r);
  714. #ifdef CONFIG_ARCH_MESON6
  715. if (vf->type & VIDTYPE_VIU_NV21) {
  716. WRITE_MPEG_REG(VD1_IF0_GEN_REG2, 1);
  717. } else {
  718. WRITE_MPEG_REG(VD1_IF0_GEN_REG2, 0);
  719. }
  720. #endif
  721. /* chroma formatter */
  722. if (vf->type & VIDTYPE_VIU_444) {
  723. WRITE_MPEG_REG(VIU_VD1_FMT_CTRL, HFORMATTER_YC_RATIO_1_1);
  724. WRITE_MPEG_REG(VIU_VD2_FMT_CTRL, HFORMATTER_YC_RATIO_1_1);
  725. } else if (vf->type & VIDTYPE_VIU_FIELD) {
  726. vini_phase = 0xc << VFORMATTER_INIPHASE_BIT;
  727. vphase = ((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT;
  728. WRITE_MPEG_REG(VIU_VD1_FMT_CTRL,
  729. HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
  730. VFORMATTER_RPTLINE0_EN | vini_phase | vphase | VFORMATTER_EN);
  731. WRITE_MPEG_REG(VIU_VD2_FMT_CTRL,
  732. HFORMATTER_YC_RATIO_2_1 | HFORMATTER_EN |
  733. VFORMATTER_RPTLINE0_EN | vini_phase | vphase | VFORMATTER_EN);
  734. } else if (vf->type & VIDTYPE_MVC) {
  735. WRITE_MPEG_REG(VIU_VD1_FMT_CTRL,
  736. HFORMATTER_YC_RATIO_2_1 |
  737. HFORMATTER_EN |
  738. VFORMATTER_RPTLINE0_EN |
  739. (0xe << VFORMATTER_INIPHASE_BIT) |
  740. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  741. VFORMATTER_EN);
  742. WRITE_MPEG_REG(VIU_VD2_FMT_CTRL,
  743. HFORMATTER_YC_RATIO_2_1 |
  744. HFORMATTER_EN |
  745. VFORMATTER_RPTLINE0_EN |
  746. (0xa << VFORMATTER_INIPHASE_BIT) |
  747. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  748. VFORMATTER_EN);
  749. } else if ((vf->type & VIDTYPE_INTERLACE) &&
  750. (((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP))) {
  751. WRITE_MPEG_REG(VIU_VD1_FMT_CTRL,
  752. HFORMATTER_YC_RATIO_2_1 |
  753. HFORMATTER_EN |
  754. VFORMATTER_RPTLINE0_EN |
  755. (0xe << VFORMATTER_INIPHASE_BIT) |
  756. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  757. VFORMATTER_EN);
  758. WRITE_MPEG_REG(VIU_VD2_FMT_CTRL,
  759. HFORMATTER_YC_RATIO_2_1 |
  760. HFORMATTER_EN |
  761. VFORMATTER_RPTLINE0_EN |
  762. (0xe << VFORMATTER_INIPHASE_BIT) |
  763. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  764. VFORMATTER_EN);
  765. } else {
  766. WRITE_MPEG_REG(VIU_VD1_FMT_CTRL,
  767. HFORMATTER_YC_RATIO_2_1 |
  768. HFORMATTER_EN |
  769. VFORMATTER_RPTLINE0_EN |
  770. (0xa << VFORMATTER_INIPHASE_BIT) |
  771. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  772. VFORMATTER_EN);
  773. WRITE_MPEG_REG(VIU_VD2_FMT_CTRL,
  774. HFORMATTER_YC_RATIO_2_1 |
  775. HFORMATTER_EN |
  776. VFORMATTER_RPTLINE0_EN |
  777. (0xa << VFORMATTER_INIPHASE_BIT) |
  778. (((vf->type & VIDTYPE_VIU_422) ? 0x10 : 0x08) << VFORMATTER_PHASE_BIT) |
  779. VFORMATTER_EN);
  780. }
  781. /* LOOP/SKIP pattern */
  782. pat = vpat[frame_par->vscale_skip_count];
  783. if (vf->type & VIDTYPE_VIU_FIELD) {
  784. loop = 0;
  785. if (vf->type & VIDTYPE_INTERLACE) {
  786. pat = vpat[frame_par->vscale_skip_count >> 1];
  787. }
  788. } else if (vf->type & VIDTYPE_MVC) {
  789. loop = 0x11;
  790. pat = 0x80;
  791. } else if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
  792. loop = 0x11;
  793. pat <<= 4;
  794. } else {
  795. loop = 0;
  796. }
  797. WRITE_MPEG_REG(VD1_IF0_RPT_LOOP,
  798. (loop << VDIF_CHROMA_LOOP1_BIT) |
  799. (loop << VDIF_LUMA_LOOP1_BIT) |
  800. (loop << VDIF_CHROMA_LOOP0_BIT) |
  801. (loop << VDIF_LUMA_LOOP0_BIT));
  802. WRITE_MPEG_REG(VD2_IF0_RPT_LOOP,
  803. (loop << VDIF_CHROMA_LOOP1_BIT) |
  804. (loop << VDIF_LUMA_LOOP1_BIT) |
  805. (loop << VDIF_CHROMA_LOOP0_BIT) |
  806. (loop << VDIF_LUMA_LOOP0_BIT));
  807. WRITE_MPEG_REG(VD1_IF0_LUMA0_RPT_PAT, pat);
  808. WRITE_MPEG_REG(VD1_IF0_CHROMA0_RPT_PAT, pat);
  809. WRITE_MPEG_REG(VD1_IF0_LUMA1_RPT_PAT, pat);
  810. WRITE_MPEG_REG(VD1_IF0_CHROMA1_RPT_PAT, pat);
  811. if (vf->type & VIDTYPE_MVC)
  812. pat = 0x88;
  813. WRITE_MPEG_REG(VD2_IF0_LUMA0_RPT_PAT, pat);
  814. WRITE_MPEG_REG(VD2_IF0_CHROMA0_RPT_PAT, pat);
  815. WRITE_MPEG_REG(VD2_IF0_LUMA1_RPT_PAT, pat);
  816. WRITE_MPEG_REG(VD2_IF0_CHROMA1_RPT_PAT, pat);
  817. /* picture 0/1 control */
  818. if (((vf->type & VIDTYPE_INTERLACE) == 0) &&
  819. ((vf->type & VIDTYPE_VIU_FIELD) == 0) &&
  820. ((vf->type & VIDTYPE_MVC) == 0)) {
  821. /* progressive frame in two pictures */
  822. WRITE_MPEG_REG(VD1_IF0_LUMA_PSEL,
  823. (2 << 26) | /* two pic mode */
  824. (2 << 24) | /* use own last line */
  825. (2 << 8) | /* toggle pic 0 and 1, use pic0 first */
  826. (0x01)); /* loop pattern */
  827. WRITE_MPEG_REG(VD1_IF0_CHROMA_PSEL,
  828. (2 << 26) | /* two pic mode */
  829. (2 << 24) | /* use own last line */
  830. (2 << 8) | /* toggle pic 0 and 1, use pic0 first */
  831. (0x01)); /* loop pattern */
  832. } else {
  833. WRITE_MPEG_REG(VD1_IF0_LUMA_PSEL, 0);
  834. WRITE_MPEG_REG(VD1_IF0_CHROMA_PSEL, 0);
  835. WRITE_MPEG_REG(VD2_IF0_LUMA_PSEL, 0);
  836. WRITE_MPEG_REG(VD2_IF0_CHROMA_PSEL, 0);
  837. }
  838. }
  839. static int detect_vout_type(void)
  840. {
  841. #if defined(CONFIG_AM_TCON_OUTPUT)
  842. return VOUT_TYPE_PROG;
  843. #else
  844. int vout_type;
  845. int encp_enable = READ_MPEG_REG(ENCP_VIDEO_EN) & 1;
  846. if (encp_enable) {
  847. if (READ_MPEG_REG(ENCP_VIDEO_MODE) & (1 << 12)) {
  848. /* 1080I */
  849. if (READ_MPEG_REG(VENC_ENCP_LINE) < 562) {
  850. vout_type = VOUT_TYPE_TOP_FIELD;
  851. } else {
  852. vout_type = VOUT_TYPE_BOT_FIELD;
  853. }
  854. } else {
  855. vout_type = VOUT_TYPE_PROG;
  856. }
  857. } else {
  858. vout_type = (READ_MPEG_REG(VENC_STATA) & 1) ?
  859. VOUT_TYPE_BOT_FIELD : VOUT_TYPE_TOP_FIELD;
  860. }
  861. return vout_type;
  862. #endif
  863. }
  864. #ifdef INTERLACE_FIELD_MATCH_PROCESS
  865. static inline bool interlace_field_type_match(int vout_type, vframe_t *vf)
  866. {
  867. if (DUR2PTS(vf->duration) != vsync_pts_inc) {
  868. return false;
  869. }
  870. if ((vout_type == VOUT_TYPE_TOP_FIELD) &&
  871. ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP)) {
  872. return true;
  873. } else if ((vout_type == VOUT_TYPE_BOT_FIELD) &&
  874. ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_BOTTOM)) {
  875. return true;
  876. }
  877. return false;
  878. }
  879. #endif
  880. static int calc_hold_line(void)
  881. {
  882. if ((READ_MPEG_REG(ENCI_VIDEO_EN) & 1) == 0) {
  883. return READ_MPEG_REG(ENCP_VIDEO_VAVON_BLINE) >> 1;
  884. } else {
  885. return READ_MPEG_REG(VFIFO2VD_LINE_TOP_START) >> 1;
  886. }
  887. }
  888. #ifdef SLOW_SYNC_REPEAT
  889. /* add a new function to check if current display frame has been
  890. displayed for its duration */
  891. static inline bool duration_expire(vframe_t *cur_vf, vframe_t *next_vf, u32 dur)
  892. {
  893. u32 pts;
  894. s32 dur_disp;
  895. static s32 rpt_tab_idx = 0;
  896. static const u32 rpt_tab[4] = {0x100, 0x100, 0x300, 0x300};
  897. if ((cur_vf == NULL) || (cur_dispbuf == &vf_local)) {
  898. return true;
  899. }
  900. pts = next_vf->pts;
  901. if (pts == 0) {
  902. dur_disp = DUR2PTS(cur_vf->duration);
  903. } else {
  904. dur_disp = pts - timestamp_vpts_get();
  905. }
  906. if ((dur << 8) >= (dur_disp * rpt_tab[rpt_tab_idx & 3])) {
  907. rpt_tab_idx = (rpt_tab_idx + 1) & 3;
  908. return true;
  909. } else {
  910. return false;
  911. }
  912. }
  913. #endif
  914. #define VPTS_RESET_THRO
  915. static inline bool vpts_expire(vframe_t *cur_vf, vframe_t *next_vf)
  916. {
  917. u32 pts = next_vf->pts;
  918. #ifdef VIDEO_PTS_CHASE
  919. u32 vid_pts, scr_pts;
  920. #endif
  921. u32 systime;
  922. if ((cur_vf == NULL) || (cur_dispbuf == &vf_local) || debugflags & DEBUG_FLAG_FFPLAY) {
  923. return true;
  924. }
  925. if ((trickmode_i == 1) || ((trickmode_fffb == 1))) {
  926. if (0 == atomic_read(&trickmode_framedone)) {
  927. return true;
  928. } else {
  929. return false;
  930. }
  931. }
  932. if (next_vf->duration == 0) {
  933. return true;
  934. }
  935. systime = timestamp_pcrscr_get();
  936. if ((pts == 0) && (cur_dispbuf != &vf_local)) {
  937. pts = timestamp_vpts_get() + (cur_vf ? DUR2PTS(cur_vf->duration) : 0);
  938. }
  939. /* check video PTS discontinuity */
  940. else if (abs(systime - pts) > tsync_vpts_discontinuity_margin()) {
  941. pts = timestamp_vpts_get() + (cur_vf ? DUR2PTS(cur_vf->duration) : 0);
  942. if ((systime - pts) >= 0) {
  943. tsync_avevent_locked(VIDEO_TSTAMP_DISCONTINUITY, next_vf->pts);
  944. printk("video discontinue, system=0x%x vpts=0x%x\n", systime, pts);
  945. return true;
  946. }
  947. }
  948. #ifdef VIDEO_PTS_CHASE
  949. vid_pts = timestamp_vpts_get();
  950. scr_pts = timestamp_pcrscr_get();
  951. vid_pts += vsync_pts_inc;
  952. if(av_sync_flag){
  953. if(vpts_chase){
  954. if((abs(vid_pts-scr_pts)<6000) || (abs(vid_pts-scr_pts)>90000)){
  955. vpts_chase = 0;
  956. printk("leave vpts chase mode, diff:%d\n", vid_pts-scr_pts);
  957. }
  958. }else if((abs(vid_pts-scr_pts)>9000) && (abs(vid_pts-scr_pts)<90000)){
  959. vpts_chase = 1;
  960. if(vid_pts<scr_pts)
  961. vpts_chase_pts_diff = 50;
  962. else
  963. vpts_chase_pts_diff = -50;
  964. vpts_chase_counter = ((int)(scr_pts-vid_pts))/vpts_chase_pts_diff;
  965. printk("enter vpts chase mode, diff:%d\n", vid_pts-scr_pts);
  966. }else if(abs(vid_pts-scr_pts)>=90000){
  967. printk("video pts discontinue, diff:%d\n", vid_pts-scr_pts);
  968. }
  969. }else{
  970. vpts_chase = 0;
  971. }
  972. if(vpts_chase){
  973. u32 curr_pts = scr_pts-vpts_chase_pts_diff*vpts_chase_counter;
  974. //printk("vchase pts %d, %d, %d, %d, %d\n", curr_pts, scr_pts, curr_pts-scr_pts, vid_pts, vpts_chase_counter);
  975. return ((int)(curr_pts-pts)) >= 0;
  976. }else{
  977. int aud_start = (timestamp_apts_get()!=-1);
  978. if(!av_sync_flag && aud_start && (abs(scr_pts-pts)<9000) && ((int)(scr_pts-pts)<0)){
  979. av_sync_flag=1;
  980. printk("av sync ok\n");
  981. }
  982. return ((int)(scr_pts-pts)) >= 0;
  983. }
  984. #else
  985. return ((int)(timestamp_pcrscr_get() - pts) >= 0);
  986. #endif
  987. }
  988. extern int check_and_set_clk81(void);
  989. static void vsync_notify(void)
  990. {
  991. if (video_notify_flag & VIDEO_NOTIFY_TRICK_WAIT) {
  992. wake_up_interruptible(&amvideo_trick_wait);
  993. video_notify_flag &= ~VIDEO_NOTIFY_TRICK_WAIT;
  994. }
  995. if (video_notify_flag & VIDEO_NOTIFY_FRAME_WAIT) {
  996. video_notify_flag &= ~VIDEO_NOTIFY_FRAME_WAIT;
  997. vf_notify_provider(RECEIVER_NAME, VFRAME_EVENT_RECEIVER_FRAME_WAIT, NULL);
  998. }
  999. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1000. if (video_notify_flag & VIDEO_NOTIFY_POS_CHANGED) {
  1001. video_notify_flag &= ~VIDEO_NOTIFY_POS_CHANGED;
  1002. vf_notify_provider(RECEIVER_NAME, VFRAME_EVENT_RECEIVER_POS_CHANGED, NULL);
  1003. }
  1004. #endif
  1005. if (video_notify_flag & (VIDEO_NOTIFY_PROVIDER_GET | VIDEO_NOTIFY_PROVIDER_PUT)) {
  1006. int event = 0;
  1007. if (video_notify_flag & VIDEO_NOTIFY_PROVIDER_GET)
  1008. event |= VFRAME_EVENT_RECEIVER_GET;
  1009. if (video_notify_flag & VIDEO_NOTIFY_PROVIDER_PUT)
  1010. event |= VFRAME_EVENT_RECEIVER_PUT;
  1011. vf_notify_provider(RECEIVER_NAME, event, NULL);
  1012. video_notify_flag &= ~(VIDEO_NOTIFY_PROVIDER_GET | VIDEO_NOTIFY_PROVIDER_PUT);
  1013. }
  1014. check_and_set_clk81();
  1015. }
  1016. #ifdef FIQ_VSYNC
  1017. static irqreturn_t vsync_bridge_isr(int irq, void *dev_id)
  1018. {
  1019. vsync_notify();
  1020. return IRQ_HANDLED;
  1021. }
  1022. #endif
  1023. #ifdef FIQ_VSYNC
  1024. void vsync_fisr(void)
  1025. #else
  1026. static irqreturn_t vsync_isr(int irq, void *dev_id)
  1027. #endif
  1028. {
  1029. int hold_line;
  1030. #ifdef CONFIG_AM_DEINTERLACE
  1031. int deinterlace_mode;
  1032. #endif
  1033. s32 i, vout_type;
  1034. vframe_t *vf;
  1035. #ifdef CONFIG_AM_VIDEO_LOG
  1036. int toggle_cnt;
  1037. #endif
  1038. #ifdef CONFIG_AM_DEINTERLACE
  1039. deinterlace_mode = get_deinterlace_mode();
  1040. #endif
  1041. #ifdef CONFIG_AM_VIDEO_LOG
  1042. toggle_cnt = 0;
  1043. #endif
  1044. vsync_count ++;
  1045. timer_count ++;
  1046. vout_type = detect_vout_type();
  1047. hold_line = calc_hold_line();
  1048. timestamp_pcrscr_inc(vsync_pts_inc);
  1049. timestamp_apts_inc(vsync_pts_inc);
  1050. #ifdef VIDEO_PTS_CHASE
  1051. if(vpts_chase){
  1052. vpts_chase_counter--;
  1053. }
  1054. #endif
  1055. #ifdef SLOW_SYNC_REPEAT
  1056. frame_repeat_count++;
  1057. #endif
  1058. if (atomic_read(&video_unreg_flag))
  1059. goto exit;
  1060. if (osd_prov && osd_prov->ops && osd_prov->ops->get){
  1061. vf = osd_prov->ops->get(osd_prov->op_arg);
  1062. if(vf){
  1063. vf->source_type = VFRAME_SOURCE_TYPE_OSD;
  1064. vsync_toggle_frame(vf);
  1065. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  1066. printk("[video4osd] toggle osd_vframe {%d,%d}\n", vf->width, vf->height);
  1067. }
  1068. goto SET_FILTER;
  1069. }
  1070. }
  1071. if ((!cur_dispbuf) || (cur_dispbuf == &vf_local)) {
  1072. vf = video_vf_peek();
  1073. if (vf) {
  1074. tsync_avevent_locked(VIDEO_START,
  1075. (vf->pts) ? vf->pts : timestamp_vpts_get());
  1076. #ifdef SLOW_SYNC_REPEAT
  1077. frame_repeat_count = 0;
  1078. #endif
  1079. } else if ((cur_dispbuf == &vf_local) && (video_property_changed)) {
  1080. if (!(blackout|force_blackout)) {
  1081. #ifdef CONFIG_AM_DEINTERLACE
  1082. if ((deinterlace_mode == 0) || (cur_dispbuf->duration == 0)
  1083. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  1084. || (cur_dispbuf->width > 720)
  1085. #endif
  1086. )
  1087. #endif
  1088. {
  1089. /* setting video display property in unregister mode */
  1090. u32 cur_index = READ_MPEG_REG(VD1_IF0_CANVAS0);
  1091. cur_dispbuf->canvas0Addr = cur_index ;
  1092. }
  1093. vsync_toggle_frame(cur_dispbuf);
  1094. } else {
  1095. video_property_changed = false;
  1096. }
  1097. } else {
  1098. goto SET_FILTER;
  1099. }
  1100. }
  1101. /* buffer switch management */
  1102. vf = video_vf_peek();
  1103. /* setting video display property in underflow mode */
  1104. if ((!vf) && cur_dispbuf && (video_property_changed)) {
  1105. vsync_toggle_frame(cur_dispbuf);
  1106. }
  1107. while (vf) {
  1108. if (vpts_expire(cur_dispbuf, vf)
  1109. #ifdef INTERLACE_FIELD_MATCH_PROCESS
  1110. || interlace_field_type_match(vout_type, vf)
  1111. #endif
  1112. ) {
  1113. amlog_mask(LOG_MASK_TIMESTAMP,
  1114. "VIDEO_PTS = 0x%x, cur_dur=0x%x, next_pts=0x%x, scr = 0x%x\n",
  1115. timestamp_vpts_get(),
  1116. (cur_dispbuf) ? cur_dispbuf->duration : 0,
  1117. vf->pts,
  1118. timestamp_pcrscr_get());
  1119. amlog_mask_if(toggle_cnt > 0, LOG_MASK_FRAMESKIP, "skipped\n");
  1120. vf = video_vf_get();
  1121. force_blackout = 0;
  1122. vsync_toggle_frame(vf);
  1123. if (trickmode_fffb == 1) {
  1124. atomic_set(&trickmode_framedone, 1);
  1125. video_notify_flag |= VIDEO_NOTIFY_TRICK_WAIT;
  1126. break;
  1127. }
  1128. #ifdef SLOW_SYNC_REPEAT
  1129. frame_repeat_count = 0;
  1130. #endif
  1131. vf = video_vf_peek();
  1132. } else {
  1133. #ifdef SLOW_SYNC_REPEAT
  1134. /* check if current frame's duration has expired, in this example
  1135. * it compares current frame display duration with 1/1/1/1.5 frame duration
  1136. * every 4 frames there will be one frame play longer than usual.
  1137. * you can adjust this array for any slow sync control as you want.
  1138. * The playback can be smoother than previous method.
  1139. */
  1140. if (duration_expire(cur_dispbuf, vf, frame_repeat_count * vsync_pts_inc) && timestamp_pcrscr_enable_state()) {
  1141. amlog_mask(LOG_MASK_SLOWSYNC,
  1142. "slow sync toggle, frame_repeat_count = %d\n",
  1143. frame_repeat_count);
  1144. amlog_mask(LOG_MASK_SLOWSYNC,
  1145. "system time = 0x%x, video time = 0x%x\n",
  1146. timestamp_pcrscr_get(), timestamp_vpts_get());
  1147. vf = video_vf_get();
  1148. vsync_toggle_frame(vf);
  1149. frame_repeat_count = 0;
  1150. vf = video_vf_peek();
  1151. } else
  1152. #endif
  1153. /* setting video display property in pause mode */
  1154. if (video_property_changed && cur_dispbuf) {
  1155. if (blackout|force_blackout) {
  1156. if (cur_dispbuf != &vf_local) {
  1157. vsync_toggle_frame(cur_dispbuf);
  1158. }
  1159. } else {
  1160. vsync_toggle_frame(cur_dispbuf);
  1161. }
  1162. }
  1163. break;
  1164. }
  1165. #ifdef CONFIG_AM_VIDEO_LOG
  1166. toggle_cnt++;
  1167. #endif
  1168. }
  1169. SET_FILTER:
  1170. /* filter setting management */
  1171. if ((frame_par_ready_to_set) || (frame_par_force_to_set)) {
  1172. cur_frame_par = next_frame_par;
  1173. }
  1174. if (cur_dispbuf) {
  1175. f2v_vphase_t *vphase;
  1176. u32 vin_type = cur_dispbuf->type & VIDTYPE_TYPEMASK;
  1177. #ifdef CONFIG_AM_DEINTERLACE
  1178. if ((deinterlace_mode == 0) || (cur_dispbuf->duration == 0)
  1179. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  1180. || (cur_dispbuf->width > 720)
  1181. #endif
  1182. )
  1183. #endif
  1184. {
  1185. viu_set_dcu(cur_frame_par, cur_dispbuf);
  1186. }
  1187. /* vertical phase */
  1188. vphase = &cur_frame_par->VPP_vf_ini_phase_[vpp_phase_table[vin_type][vout_type]];
  1189. WRITE_MPEG_REG(VPP_VSC_INI_PHASE, ((u32)(vphase->phase) << 8));
  1190. if (vphase->repeat_skip >= 0) {
  1191. /* skip lines */
  1192. WRITE_MPEG_REG_BITS(VPP_VSC_PHASE_CTRL,
  1193. skip_tab[vphase->repeat_skip],
  1194. VPP_PHASECTL_INIRCVNUMT_BIT,
  1195. VPP_PHASECTL_INIRCVNUM_WID +
  1196. VPP_PHASECTL_INIRPTNUM_WID);
  1197. } else {
  1198. /* repeat first line */
  1199. WRITE_MPEG_REG_BITS(VPP_VSC_PHASE_CTRL, 4,
  1200. VPP_PHASECTL_INIRCVNUMT_BIT,
  1201. VPP_PHASECTL_INIRCVNUM_WID);
  1202. WRITE_MPEG_REG_BITS(VPP_VSC_PHASE_CTRL,
  1203. 1 - vphase->repeat_skip,
  1204. VPP_PHASECTL_INIRPTNUMT_BIT,
  1205. VPP_PHASECTL_INIRPTNUM_WID);
  1206. }
  1207. }
  1208. if (((frame_par_ready_to_set) || (frame_par_force_to_set)) &&
  1209. (cur_frame_par)) {
  1210. vppfilter_mode_t *vpp_filter = &cur_frame_par->vpp_filter;
  1211. if (cur_dispbuf) {
  1212. u32 zoom_start_y, zoom_end_y;
  1213. if (cur_dispbuf->type & VIDTYPE_INTERLACE) {
  1214. if (cur_dispbuf->type & VIDTYPE_VIU_FIELD) {
  1215. zoom_start_y = cur_frame_par->VPP_vd_start_lines_ >> 1;
  1216. zoom_end_y = (cur_frame_par->VPP_vd_end_lines_ + 1) >> 1;
  1217. } else {
  1218. zoom_start_y = cur_frame_par->VPP_vd_start_lines_;
  1219. zoom_end_y = cur_frame_par->VPP_vd_end_lines_;
  1220. }
  1221. } else {
  1222. if (cur_dispbuf->type & VIDTYPE_VIU_FIELD) {
  1223. zoom_start_y = cur_frame_par->VPP_vd_start_lines_;
  1224. zoom_end_y = cur_frame_par->VPP_vd_end_lines_;
  1225. } else {
  1226. zoom_start_y = cur_frame_par->VPP_vd_start_lines_ >> 1;
  1227. zoom_end_y = (cur_frame_par->VPP_vd_end_lines_ + 1) >> 1;
  1228. }
  1229. }
  1230. zoom_start_x_lines = cur_frame_par->VPP_hd_start_lines_;
  1231. zoom_end_x_lines = cur_frame_par->VPP_hd_end_lines_;
  1232. zoom_display_horz();
  1233. zoom_start_y_lines = zoom_start_y;
  1234. zoom_end_y_lines = zoom_end_y;
  1235. zoom_display_vert();
  1236. }
  1237. /* vpp filters */
  1238. SET_MPEG_REG_MASK(VPP_SC_MISC,
  1239. VPP_SC_TOP_EN | VPP_SC_VERT_EN | VPP_SC_HORZ_EN);
  1240. /* horitontal filter settings */
  1241. WRITE_MPEG_REG_BITS(VPP_SC_MISC,
  1242. vpp_filter->vpp_horz_coeff[0],
  1243. VPP_SC_HBANK_LENGTH_BIT,
  1244. VPP_SC_BANK_LENGTH_WID);
  1245. if (vpp_filter->vpp_horz_coeff[1] & 0x8000) {
  1246. WRITE_MPEG_REG(VPP_SCALE_COEF_IDX, VPP_COEF_HORZ | VPP_COEF_9BIT);
  1247. } else {
  1248. WRITE_MPEG_REG(VPP_SCALE_COEF_IDX, VPP_COEF_HORZ);
  1249. }
  1250. for (i = 0; i < (vpp_filter->vpp_horz_coeff[1] & 0xff); i++) {
  1251. WRITE_MPEG_REG(VPP_SCALE_COEF, vpp_filter->vpp_horz_coeff[i + 2]);
  1252. }
  1253. /* vertical filter settings */
  1254. WRITE_MPEG_REG_BITS(VPP_SC_MISC,
  1255. vpp_filter->vpp_vert_coeff[0],
  1256. VPP_SC_VBANK_LENGTH_BIT,
  1257. VPP_SC_BANK_LENGTH_WID);
  1258. WRITE_MPEG_REG(VPP_SCALE_COEF_IDX, VPP_COEF_VERT);
  1259. for (i = 0; i < vpp_filter->vpp_vert_coeff[1]; i++) {
  1260. WRITE_MPEG_REG(VPP_SCALE_COEF,
  1261. vpp_filter->vpp_vert_coeff[i + 2]);
  1262. }
  1263. WRITE_MPEG_REG(VPP_PIC_IN_HEIGHT,
  1264. cur_frame_par->VPP_pic_in_height_);
  1265. WRITE_MPEG_REG_BITS(VPP_HSC_PHASE_CTRL,
  1266. cur_frame_par->VPP_hf_ini_phase_,
  1267. VPP_HSC_TOP_INI_PHASE_BIT,
  1268. VPP_HSC_TOP_INI_PHASE_WID);
  1269. WRITE_MPEG_REG(VPP_POSTBLEND_VD1_H_START_END,
  1270. ((cur_frame_par->VPP_post_blend_vd_h_start_ & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  1271. ((cur_frame_par->VPP_post_blend_vd_h_end_ & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  1272. WRITE_MPEG_REG(VPP_POSTBLEND_VD1_V_START_END,
  1273. ((cur_frame_par->VPP_post_blend_vd_v_start_ & VPP_VD_SIZE_MASK) << VPP_VD1_START_BIT) |
  1274. ((cur_frame_par->VPP_post_blend_vd_v_end_ & VPP_VD_SIZE_MASK) << VPP_VD1_END_BIT));
  1275. WRITE_MPEG_REG(VPP_POSTBLEND_H_SIZE, cur_frame_par->VPP_post_blend_h_size_);
  1276. vpp_settings_h(cur_frame_par);
  1277. vpp_settings_v(cur_frame_par);
  1278. frame_par_ready_to_set = 0;
  1279. frame_par_force_to_set = 0;
  1280. } /* VPP one time settings */
  1281. wait_sync = 0;
  1282. #ifdef CONFIG_AM_DEINTERLACE
  1283. if ((deinterlace_mode != 0) && cur_dispbuf && (cur_dispbuf->duration > 0)
  1284. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  1285. && (cur_dispbuf->width <= 720)
  1286. #endif
  1287. ) {
  1288. run_deinterlace(zoom_start_x_lines, zoom_end_x_lines, zoom_start_y_lines, zoom_end_y_lines, cur_dispbuf->type_backup, cur_dispbuf->blend_mode, hold_line);
  1289. }
  1290. else
  1291. #endif
  1292. if(cur_dispbuf && cur_dispbuf->process_fun && (cur_dispbuf->duration > 0)){
  1293. /* for new deinterlace driver */
  1294. cur_dispbuf->process_fun(cur_dispbuf->private_data, zoom_start_x_lines|(cur_frame_par->vscale_skip_count<<24), zoom_end_x_lines, zoom_start_y_lines, zoom_end_y_lines);
  1295. }
  1296. exit:
  1297. if(timer_count > 50){
  1298. timer_count = 0 ;
  1299. video_notify_flag |= VIDEO_NOTIFY_FRAME_WAIT;
  1300. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1301. if((video_scaler_mode)&&(scaler_pos_changed)){
  1302. video_notify_flag |= VIDEO_NOTIFY_POS_CHANGED;
  1303. scaler_pos_changed = 0;
  1304. }else{
  1305. scaler_pos_changed = 0;
  1306. video_notify_flag &= ~VIDEO_NOTIFY_POS_CHANGED;
  1307. }
  1308. #endif
  1309. }
  1310. #ifdef FIQ_VSYNC
  1311. if (video_notify_flag)
  1312. fiq_bridge_pulse_trigger(&vsync_fiq_bridge);
  1313. #else
  1314. if (video_notify_flag)
  1315. vsync_notify();
  1316. return IRQ_HANDLED;
  1317. #endif
  1318. }
  1319. static int alloc_keep_buffer(void)
  1320. {
  1321. amlog_mask(LOG_MASK_KEEPBUF, "alloc_keep_buffer\n");
  1322. keep_y_addr = __get_free_pages(GFP_KERNEL, get_order(Y_BUFFER_SIZE));
  1323. if (!keep_y_addr) {
  1324. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to alloc y addr\n", __FUNCTION__);
  1325. goto err1;
  1326. }
  1327. keep_y_addr_remap = ioremap_nocache(virt_to_phys((u8 *)keep_y_addr), Y_BUFFER_SIZE);
  1328. if (!keep_y_addr_remap) {
  1329. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to remap y addr\n", __FUNCTION__);
  1330. goto err2;
  1331. }
  1332. keep_u_addr = __get_free_pages(GFP_KERNEL, get_order(U_BUFFER_SIZE));
  1333. if (!keep_u_addr) {
  1334. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to alloc u addr\n", __FUNCTION__);
  1335. goto err3;
  1336. }
  1337. keep_u_addr_remap = ioremap_nocache(virt_to_phys((u8 *)keep_u_addr), U_BUFFER_SIZE);
  1338. if (!keep_u_addr_remap) {
  1339. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to remap u addr\n", __FUNCTION__);
  1340. goto err4;
  1341. }
  1342. keep_v_addr = __get_free_pages(GFP_KERNEL, get_order(V_BUFFER_SIZE));
  1343. if (!keep_v_addr) {
  1344. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to alloc v addr\n", __FUNCTION__);
  1345. goto err5;
  1346. }
  1347. keep_v_addr_remap = ioremap_nocache(virt_to_phys((u8 *)keep_v_addr), U_BUFFER_SIZE);
  1348. if (!keep_v_addr_remap) {
  1349. amlog_mask(LOG_MASK_KEEPBUF, "%s: failed to remap v addr\n", __FUNCTION__);
  1350. goto err6;
  1351. }
  1352. return 0;
  1353. err6:
  1354. free_pages(keep_v_addr, get_order(U_BUFFER_SIZE));
  1355. keep_v_addr = 0;
  1356. err5:
  1357. iounmap(keep_u_addr_remap);
  1358. keep_u_addr_remap = NULL;
  1359. err4:
  1360. free_pages(keep_u_addr, get_order(U_BUFFER_SIZE));
  1361. keep_u_addr = 0;
  1362. err3:
  1363. iounmap(keep_y_addr_remap);
  1364. keep_y_addr_remap = NULL;
  1365. err2:
  1366. free_pages(keep_y_addr, get_order(Y_BUFFER_SIZE));
  1367. keep_y_addr = 0;
  1368. err1:
  1369. return -ENOMEM;
  1370. }
  1371. void get_video_keep_buffer(ulong *addr, ulong *phys_addr)
  1372. {
  1373. if (addr) {
  1374. addr[0] = (ulong)keep_y_addr_remap;
  1375. addr[1] = (ulong)keep_u_addr_remap;
  1376. addr[2] = (ulong)keep_v_addr_remap;
  1377. }
  1378. if (phys_addr) {
  1379. phys_addr[0] = (keep_y_addr == 0) ? 0 : (ulong)virt_to_phys((u8 *)keep_y_addr);
  1380. phys_addr[1] = (keep_u_addr == 0) ? 0 : (ulong)virt_to_phys((u8 *)keep_u_addr);
  1381. phys_addr[2] = (keep_v_addr == 0) ? 0 : (ulong)virt_to_phys((u8 *)keep_v_addr);
  1382. }
  1383. }
  1384. /*********************************************************
  1385. * FIQ Routines
  1386. *********************************************************/
  1387. static void vsync_fiq_up(void)
  1388. {
  1389. #ifdef FIQ_VSYNC
  1390. request_fiq(INT_VIU_VSYNC, &vsync_fisr);
  1391. #else
  1392. int r;
  1393. r = request_irq(INT_VIU_VSYNC, &vsync_isr,
  1394. IRQF_SHARED, "vsync",
  1395. (void *)video_dev_id);
  1396. #endif
  1397. }
  1398. static void vsync_fiq_down(void)
  1399. {
  1400. #ifdef FIQ_VSYNC
  1401. free_fiq(INT_VIU_VSYNC, &vsync_fisr);
  1402. #else
  1403. free_irq(INT_VIU_VSYNC, (void *)video_dev_id);
  1404. #endif
  1405. }
  1406. int get_curren_frame_para(int* top ,int* left , int* bottom, int* right)
  1407. {
  1408. if(!cur_frame_par){
  1409. return -1;
  1410. }
  1411. *top = cur_frame_par->VPP_vd_start_lines_ ;
  1412. *left = cur_frame_par->VPP_hd_start_lines_ ;
  1413. *bottom = cur_frame_par->VPP_vd_end_lines_ ;
  1414. *right = cur_frame_par->VPP_hd_end_lines_;
  1415. return 0;
  1416. }
  1417. int get_current_vscale_skip_count(void)
  1418. {
  1419. if(cur_frame_par)
  1420. return cur_frame_par->vscale_skip_count;
  1421. else
  1422. return 0;
  1423. }
  1424. static void video_vf_unreg_provider(void)
  1425. {
  1426. ulong flags;
  1427. #ifdef CONFIG_AM_DEINTERLACE
  1428. int deinterlace_mode = get_deinterlace_mode();
  1429. #endif
  1430. atomic_set(&video_unreg_flag, 1);
  1431. spin_lock_irqsave(&lock, flags);
  1432. if (cur_dispbuf) {
  1433. vf_local = *cur_dispbuf;
  1434. cur_dispbuf = &vf_local;
  1435. }
  1436. if (trickmode_fffb) {
  1437. atomic_set(&trickmode_framedone, 0);
  1438. }
  1439. if (blackout|force_blackout) {
  1440. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1441. if(video_scaler_mode)
  1442. DisableVideoLayer_PREBELEND();
  1443. else
  1444. DisableVideoLayer();
  1445. #else
  1446. DisableVideoLayer();
  1447. #endif
  1448. }
  1449. //if (!trickmode_fffb)
  1450. {
  1451. vf_keep_current();
  1452. }
  1453. tsync_avevent(VIDEO_STOP, 0);
  1454. #ifdef CONFIG_AM_DEINTERLACE
  1455. if (deinterlace_mode == 2) {
  1456. disable_pre_deinterlace();
  1457. }
  1458. #endif
  1459. spin_unlock_irqrestore(&lock, flags);
  1460. atomic_set(&video_unreg_flag, 0);
  1461. }
  1462. static void video_vf_light_unreg_provider(void)
  1463. {
  1464. ulong flags;
  1465. spin_lock_irqsave(&lock, flags);
  1466. if (cur_dispbuf) {
  1467. vf_local = *cur_dispbuf;
  1468. cur_dispbuf = &vf_local;
  1469. }
  1470. spin_unlock_irqrestore(&lock, flags);
  1471. }
  1472. static int video_receiver_event_fun(int type, void* data, void* private_data)
  1473. {
  1474. if(type == VFRAME_EVENT_PROVIDER_UNREG){
  1475. video_vf_unreg_provider();
  1476. #ifdef CONFIG_AM_VIDEO2
  1477. set_clone_frame_rate(30, 200);
  1478. #endif
  1479. }
  1480. else if(type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG){
  1481. video_vf_light_unreg_provider();
  1482. }
  1483. else if(type == VFRAME_EVENT_PROVIDER_REG){
  1484. #ifdef CONFIG_AM_VIDEO2
  1485. char* provider_name = (char*)data;
  1486. if(strncmp(provider_name, "decoder", 7)==0
  1487. || strncmp(provider_name, "ppmgr", 5)==0){
  1488. set_clone_frame_rate(5, 0);
  1489. set_clone_frame_rate(10, 100);
  1490. }
  1491. #endif
  1492. video_vf_light_unreg_provider();
  1493. }
  1494. else if(type == VFRAME_EVENT_PROVIDER_FORCE_BLACKOUT){
  1495. force_blackout = 1;
  1496. }
  1497. return 0;
  1498. }
  1499. static int video4osd_receiver_event_fun(int type, void* data, void* private_data)
  1500. {
  1501. if(type == VFRAME_EVENT_PROVIDER_UNREG){
  1502. osd_prov = NULL;
  1503. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  1504. printk("[video4osd] clear osd_prov\n");
  1505. }
  1506. }
  1507. else if(type == VFRAME_EVENT_PROVIDER_REG){
  1508. osd_prov = vf_get_provider(RECEIVER4OSD_NAME);
  1509. if(debug_flag& DEBUG_FLAG_BLACKOUT){
  1510. printk("[video4osd] set osd_prov\n");
  1511. }
  1512. }
  1513. return 0;
  1514. }
  1515. unsigned int get_post_canvas(void)
  1516. {
  1517. return post_canvas;
  1518. }
  1519. static int canvas_dup(ulong *dst, ulong src_paddr, ulong size)
  1520. {
  1521. void __iomem *p = ioremap_wc(src_paddr, size);
  1522. if (p) {
  1523. memcpy(dst, p, size);
  1524. iounmap(p);
  1525. return 1;
  1526. }
  1527. return 0;
  1528. }
  1529. unsigned int vf_keep_current(void)
  1530. {
  1531. u32 cur_index;
  1532. u32 y_index, u_index, v_index;
  1533. canvas_t cs0,cs1,cs2,cd;
  1534. #ifdef CONFIG_AM_DEINTERLACE
  1535. int deinterlace_mode = get_deinterlace_mode();
  1536. #endif
  1537. if (blackout|force_blackout) {
  1538. return 0;
  1539. }
  1540. if (0 == (READ_MPEG_REG(VPP_MISC) & VPP_VD1_POSTBLEND)) {
  1541. return 0;
  1542. }
  1543. #ifdef CONFIG_AM_DEINTERLACE
  1544. if ((deinterlace_mode != 0) && cur_dispbuf && (cur_dispbuf->duration > 0)
  1545. #if defined(CONFIG_AM_DEINTERLACE_SD_ONLY)
  1546. && (cur_dispbuf->width <= 720)
  1547. #endif
  1548. ) {
  1549. return 0;
  1550. }
  1551. #endif
  1552. if (!keep_y_addr_remap) {
  1553. //if (alloc_keep_buffer())
  1554. return -1;
  1555. }
  1556. cur_index = READ_MPEG_REG(VD1_IF0_CANVAS0);
  1557. y_index = cur_index & 0xff;
  1558. u_index = (cur_index >> 8) & 0xff;
  1559. v_index = (cur_index >> 16) & 0xff;
  1560. if ((cur_dispbuf->type & VIDTYPE_VIU_422) == VIDTYPE_VIU_422) {
  1561. canvas_read(y_index,&cd);
  1562. if (keep_y_addr != canvas_get_addr(y_index) && /*must not the same address*/
  1563. canvas_dup(keep_y_addr_remap, canvas_get_addr(y_index), (cd.width)*(cd.height))) {
  1564. canvas_update_addr(y_index, (u32)keep_y_addr);
  1565. }
  1566. } else if ((cur_dispbuf->type & VIDTYPE_VIU_444) == VIDTYPE_VIU_444) {
  1567. canvas_read(y_index,&cd);
  1568. if (keep_y_addr != canvas_get_addr(y_index) && /*must not the same address*/
  1569. canvas_dup(keep_y_addr_remap, canvas_get_addr(y_index), (cd.width)*(cd.height))){
  1570. canvas_update_addr(y_index, (u32)keep_y_addr);
  1571. }
  1572. } else if((cur_dispbuf->type & VIDTYPE_VIU_NV21) == VIDTYPE_VIU_NV21){
  1573. canvas_read(y_index,&cs0);
  1574. canvas_read(u_index,&cs1);
  1575. if (keep_y_addr != canvas_get_addr(y_index) && /*must not the same address*/
  1576. canvas_dup(keep_y_addr_remap, canvas_get_addr(y_index), (cs0.width *cs0.height)) &&
  1577. canvas_dup(keep_u_addr_remap, canvas_get_addr(u_index), (cs1.width *cs1.height))){
  1578. canvas_update_addr(y_index, (u32)keep_y_addr);
  1579. canvas_update_addr(u_index, (u32)keep_u_addr);
  1580. }
  1581. }else{
  1582. canvas_read(y_index,&cs0);
  1583. canvas_read(u_index,&cs1);
  1584. canvas_read(v_index,&cs2);
  1585. if (keep_y_addr != canvas_get_addr(y_index) && /*must not the same address*/
  1586. canvas_dup(keep_y_addr_remap, canvas_get_addr(y_index), (cs0.width *cs0.height)) &&
  1587. canvas_dup(keep_u_addr_remap, canvas_get_addr(u_index), (cs1.width *cs1.height)) &&
  1588. canvas_dup(keep_v_addr_remap, canvas_get_addr(v_index), (cs2.width *cs2.height))) {
  1589. canvas_update_addr(y_index, (u32)keep_y_addr);
  1590. canvas_update_addr(u_index, (u32)keep_u_addr);
  1591. canvas_update_addr(v_index, (u32)keep_v_addr);
  1592. }
  1593. }
  1594. return 0;
  1595. }
  1596. EXPORT_SYMBOL(get_post_canvas);
  1597. EXPORT_SYMBOL(vf_keep_current);
  1598. u32 get_blackout_policy(void)
  1599. {
  1600. return blackout;
  1601. }
  1602. EXPORT_SYMBOL(get_blackout_policy);
  1603. /*********************************************************
  1604. * Utilities
  1605. *********************************************************/
  1606. int _video_set_disable(u32 val)
  1607. {
  1608. if ((val < VIDEO_DISABLE_NONE) || (val > VIDEO_DISABLE_FORNEXT)) {
  1609. return -EINVAL;
  1610. }
  1611. disable_video = val;
  1612. if (disable_video != VIDEO_DISABLE_NONE) {
  1613. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1614. if(video_scaler_mode)
  1615. DisableVideoLayer_PREBELEND();
  1616. else
  1617. DisableVideoLayer();
  1618. #else
  1619. DisableVideoLayer();
  1620. #endif
  1621. if ((disable_video == VIDEO_DISABLE_FORNEXT) && cur_dispbuf && (cur_dispbuf != &vf_local))
  1622. video_property_changed = true;
  1623. } else {
  1624. if (cur_dispbuf && (cur_dispbuf != &vf_local)) {
  1625. EnableVideoLayer();
  1626. }
  1627. }
  1628. return 0;
  1629. }
  1630. static void _set_video_window(int *p)
  1631. {
  1632. int w, h;
  1633. int *parsed = p;
  1634. w = parsed[2] - parsed[0] + 1;
  1635. h = parsed[3] - parsed[1] + 1;
  1636. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1637. if(video_scaler_mode){
  1638. if ((w == 1) && (h == 1)){
  1639. w= 0;
  1640. h = 0;
  1641. }
  1642. if((content_left!=parsed[0])||(content_top!=parsed[1])||(content_w!=w)||(content_h!=h))
  1643. scaler_pos_changed = 1;
  1644. content_left = parsed[0];
  1645. content_top = parsed[1];
  1646. content_w = w;
  1647. content_h = h;
  1648. //video_notify_flag = video_notify_flag|VIDEO_NOTIFY_POS_CHANGED;
  1649. }else
  1650. #endif
  1651. {
  1652. if ((w == 1) && (h == 1)) {
  1653. w = h = 0;
  1654. vpp_set_video_layer_position(parsed[0], parsed[1], 0, 0);
  1655. } else if ((w > 0) && (h > 0)) {
  1656. vpp_set_video_layer_position(parsed[0], parsed[1], w, h);
  1657. }
  1658. }
  1659. video_property_changed = true;
  1660. }
  1661. /*********************************************************
  1662. * /dev/amvideo APIs
  1663. *********************************************************/
  1664. static int amvideo_open(struct inode *inode, struct file *file)
  1665. {
  1666. return 0;
  1667. }
  1668. static int amvideo_release(struct inode *inode, struct file *file)
  1669. {
  1670. if (blackout|force_blackout) {
  1671. ///DisableVideoLayer();/*don't need it ,it have problem on pure music playing*/
  1672. }
  1673. return 0;
  1674. }
  1675. static long amvideo_ioctl(struct file *file,
  1676. unsigned int cmd, ulong arg)
  1677. {
  1678. long ret = 0;
  1679. void *argp = (void *)arg;
  1680. switch (cmd) {
  1681. case AMSTREAM_IOC_TRICKMODE:
  1682. if (arg == TRICKMODE_I) {
  1683. trickmode_i = 1;
  1684. } else if (arg == TRICKMODE_FFFB) {
  1685. trickmode_fffb = 1;
  1686. } else {
  1687. trickmode_i = 0;
  1688. trickmode_fffb = 0;
  1689. }
  1690. atomic_set(&trickmode_framedone, 0);
  1691. tsync_trick_mode(trickmode_fffb);
  1692. break;
  1693. case AMSTREAM_IOC_TRICK_STAT:
  1694. *((u32 *)arg) = atomic_read(&trickmode_framedone);
  1695. break;
  1696. case AMSTREAM_IOC_VPAUSE:
  1697. tsync_avevent(VIDEO_PAUSE, arg);
  1698. break;
  1699. case AMSTREAM_IOC_AVTHRESH:
  1700. tsync_set_avthresh(arg);
  1701. break;
  1702. case AMSTREAM_IOC_SYNCTHRESH:
  1703. tsync_set_syncthresh(arg);
  1704. break;
  1705. case AMSTREAM_IOC_SYNCENABLE:
  1706. tsync_set_enable(arg);
  1707. break;
  1708. case AMSTREAM_IOC_SET_SYNC_ADISCON:
  1709. tsync_set_sync_adiscont(arg);
  1710. break;
  1711. case AMSTREAM_IOC_SET_SYNC_VDISCON:
  1712. tsync_set_sync_vdiscont(arg);
  1713. break;
  1714. case AMSTREAM_IOC_GET_SYNC_ADISCON:
  1715. *((u32 *)arg) = tsync_get_sync_adiscont();
  1716. break;
  1717. case AMSTREAM_IOC_GET_SYNC_VDISCON:
  1718. *((u32 *)arg) = tsync_get_sync_vdiscont();
  1719. break;
  1720. case AMSTREAM_IOC_VF_STATUS: {
  1721. vframe_states_t vfsta;
  1722. vframe_states_t *states = (void *)arg;
  1723. vf_get_states(&vfsta);
  1724. if (states == NULL)
  1725. return -EINVAL;
  1726. states->vf_pool_size = vfsta.vf_pool_size;
  1727. states->buf_avail_num = vfsta.buf_avail_num;
  1728. states->buf_free_num = vfsta.buf_free_num;
  1729. states->buf_recycle_num = vfsta.buf_recycle_num;
  1730. }
  1731. break;
  1732. case AMSTREAM_IOC_GET_VIDEO_DISABLE:
  1733. *((u32 *)arg) = disable_video;
  1734. break;
  1735. case AMSTREAM_IOC_SET_VIDEO_DISABLE:
  1736. ret = _video_set_disable(arg);
  1737. break;
  1738. case AMSTREAM_IOC_GET_VIDEO_AXIS:
  1739. {
  1740. int axis[4];
  1741. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1742. if (video_scaler_mode) {
  1743. axis[0] = content_left;
  1744. axis[1] = content_top;
  1745. axis[2] = content_w;
  1746. axis[3] = content_h;
  1747. } else
  1748. #endif
  1749. {
  1750. vpp_get_video_layer_position(&axis[0], &axis[1], &axis[2], &axis[3]);
  1751. }
  1752. axis[2] = axis[0] + axis[2] - 1;
  1753. axis[3] = axis[1] + axis[3] - 1;
  1754. if (copy_to_user(argp, &axis[0], sizeof(axis)) != 0) {
  1755. ret = -EFAULT;
  1756. }
  1757. }
  1758. break;
  1759. case AMSTREAM_IOC_SET_VIDEO_AXIS:
  1760. {
  1761. int axis[4];
  1762. if (copy_from_user(axis, argp, sizeof(axis)) == 0) {
  1763. _set_video_window(axis);
  1764. } else {
  1765. ret = -EFAULT;
  1766. }
  1767. }
  1768. break;
  1769. case AMSTREAM_IOC_CLEAR_VBUF: {
  1770. unsigned long flags;
  1771. spin_lock_irqsave(&lock, flags);
  1772. cur_dispbuf = NULL;
  1773. spin_unlock_irqrestore(&lock, flags);
  1774. }
  1775. break;
  1776. case AMSTREAM_IOC_GET_SCREEN_MODE:
  1777. if (copy_to_user(argp, &wide_setting, sizeof(u32)) != 0) {
  1778. ret = -EFAULT;
  1779. }
  1780. break;
  1781. case AMSTREAM_IOC_SET_SCREEN_MODE:
  1782. {
  1783. u32 mode;
  1784. if (copy_from_user(&mode, argp, sizeof(u32)) == 0) {
  1785. if (mode >= VIDEO_WIDEOPTION_MAX) {
  1786. ret = -EINVAL;
  1787. } else if (mode != wide_setting) {
  1788. wide_setting = mode;
  1789. video_property_changed = true;
  1790. }
  1791. } else {
  1792. ret = -EFAULT;
  1793. }
  1794. }
  1795. break;
  1796. #ifndef CONFIG_ARCH_MESON6
  1797. /**********************************************************************
  1798. video enhancement ioctl
  1799. **********************************************************************/
  1800. case AMSTREAM_IOC_VE_DEBUG: {
  1801. struct ve_regs_s data;
  1802. #if 0
  1803. if (get_user((unsigned long long)data, (void __user *)arg))
  1804. #else
  1805. if (copy_from_user(&data, (void __user *)arg, sizeof(struct ve_regs_s)))
  1806. #endif
  1807. {
  1808. ret = -EFAULT;
  1809. } else {
  1810. ve_set_regs(&data);
  1811. if (!(data.mode)) { // read
  1812. #if 0
  1813. if (put_user((unsigned long long)data, (void __user *)arg))
  1814. #else
  1815. if (copy_to_user(&data, (void __user *)arg, sizeof(struct ve_regs_s)))
  1816. #endif
  1817. {
  1818. ret = -EFAULT;
  1819. }
  1820. }
  1821. }
  1822. break;
  1823. }
  1824. case AMSTREAM_IOC_VE_BEXT: {
  1825. struct ve_bext_s ve_bext;
  1826. if (copy_from_user(&ve_bext, (void __user *)arg, sizeof(struct ve_bext_s))) {
  1827. ret = -EFAULT;
  1828. break;
  1829. }
  1830. ve_set_bext(&ve_bext);
  1831. break;
  1832. }
  1833. case AMSTREAM_IOC_VE_DNLP: {
  1834. struct ve_dnlp_s ve_dnlp;
  1835. if (copy_from_user(&ve_dnlp, (void __user *)arg, sizeof(struct ve_dnlp_s))) {
  1836. ret = -EFAULT;
  1837. break;
  1838. }
  1839. ve_set_dnlp(&ve_dnlp);
  1840. break;
  1841. }
  1842. case AMSTREAM_IOC_VE_HSVS: {
  1843. struct ve_hsvs_s ve_hsvs;
  1844. if (copy_from_user(&ve_hsvs, (void __user *)arg, sizeof(struct ve_hsvs_s))) {
  1845. ret = -EFAULT;
  1846. break;
  1847. }
  1848. ve_set_hsvs(&ve_hsvs);
  1849. break;
  1850. }
  1851. case AMSTREAM_IOC_VE_CCOR: {
  1852. struct ve_ccor_s ve_ccor;
  1853. if (copy_from_user(&ve_ccor, (void __user *)arg, sizeof(struct ve_ccor_s))) {
  1854. ret = -EFAULT;
  1855. break;
  1856. }
  1857. ve_set_ccor(&ve_ccor);
  1858. break;
  1859. }
  1860. case AMSTREAM_IOC_VE_BENH: {
  1861. struct ve_benh_s ve_benh;
  1862. if (copy_from_user(&ve_benh, (void __user *)arg, sizeof(struct ve_benh_s))) {
  1863. ret = -EFAULT;
  1864. break;
  1865. }
  1866. ve_set_benh(&ve_benh);
  1867. break;
  1868. }
  1869. case AMSTREAM_IOC_VE_DEMO: {
  1870. struct ve_demo_s ve_demo;
  1871. if (copy_from_user(&ve_demo, (void __user *)arg, sizeof(struct ve_demo_s))) {
  1872. ret = -EFAULT;
  1873. break;
  1874. }
  1875. ve_set_demo(&ve_demo);
  1876. break;
  1877. }
  1878. /**********************************************************************
  1879. color management ioctl
  1880. **********************************************************************/
  1881. case AMSTREAM_IOC_CM_DEBUG: {
  1882. struct cm_regs_s data;
  1883. if (copy_from_user(&data, (void __user *)arg, sizeof(struct cm_regs_s))) {
  1884. ret = -EFAULT;
  1885. } else {
  1886. cm_set_regs(&data);
  1887. if (!(data.mode)) { // read
  1888. if (copy_to_user(&data, (void __user *)arg, sizeof(struct cm_regs_s))) {
  1889. ret = -EFAULT;
  1890. }
  1891. }
  1892. }
  1893. break;
  1894. }
  1895. case AMSTREAM_IOC_CM_REGION: {
  1896. struct cm_region_s cm_region;
  1897. if (copy_from_user(&cm_region, (void __user *)arg, sizeof(struct cm_region_s))) {
  1898. ret = -EFAULT;
  1899. break;
  1900. }
  1901. cm_set_region(&cm_region);
  1902. break;
  1903. }
  1904. case AMSTREAM_IOC_CM_TOP: {
  1905. struct cm_top_s cm_top;
  1906. if (copy_from_user(&cm_top, (void __user *)arg, sizeof(struct cm_top_s))) {
  1907. ret = -EFAULT;
  1908. break;
  1909. }
  1910. cm_set_top(&cm_top);
  1911. break;
  1912. }
  1913. case AMSTREAM_IOC_CM_DEMO: {
  1914. struct cm_demo_s cm_demo;
  1915. if (copy_from_user(&cm_demo, (void __user *)arg, sizeof(struct cm_demo_s))) {
  1916. ret = -EFAULT;
  1917. break;
  1918. }
  1919. cm_set_demo(&cm_demo);
  1920. break;
  1921. }
  1922. #endif
  1923. default:
  1924. return -EINVAL;
  1925. }
  1926. return ret;
  1927. }
  1928. static unsigned int amvideo_poll(struct file *file, poll_table *wait_table)
  1929. {
  1930. poll_wait(file, &amvideo_trick_wait, wait_table);
  1931. if (atomic_read(&trickmode_framedone)) {
  1932. atomic_set(&trickmode_framedone, 0);
  1933. return POLLOUT | POLLWRNORM;
  1934. }
  1935. return 0;
  1936. }
  1937. const static struct file_operations amvideo_fops = {
  1938. .owner = THIS_MODULE,
  1939. .open = amvideo_open,
  1940. .release = amvideo_release,
  1941. .unlocked_ioctl = amvideo_ioctl,
  1942. .poll = amvideo_poll,
  1943. };
  1944. /*********************************************************
  1945. * SYSFS property functions
  1946. *********************************************************/
  1947. #define MAX_NUMBER_PARA 10
  1948. #define AMVIDEO_CLASS_NAME "video"
  1949. static int parse_para(const char *para, int para_num, int *result)
  1950. {
  1951. char *endp;
  1952. const char *startp = para;
  1953. int *out = result;
  1954. int len = 0, count = 0;
  1955. if (!startp) {
  1956. return 0;
  1957. }
  1958. len = strlen(startp);
  1959. do {
  1960. //filter space out
  1961. while (startp && (isspace(*startp) || !isgraph(*startp)) && len) {
  1962. startp++;
  1963. len--;
  1964. }
  1965. if (len == 0) {
  1966. break;
  1967. }
  1968. *out++ = simple_strtol(startp, &endp, 0);
  1969. len -= endp - startp;
  1970. startp = endp;
  1971. count++;
  1972. } while ((endp) && (count < para_num) && (len > 0));
  1973. return count;
  1974. }
  1975. static void set_video_window(const char *para)
  1976. {
  1977. int parsed[4];
  1978. if (likely(parse_para(para, 4, parsed) == 4)) {
  1979. _set_video_window(parsed);
  1980. }
  1981. amlog_mask(LOG_MASK_SYSFS,
  1982. "video=>x0:%d,y0:%d,x1:%d,y1:%d\r\n ",
  1983. parsed[0], parsed[1], parsed[2], parsed[3]);
  1984. }
  1985. static ssize_t video_axis_show(struct class *cla, struct class_attribute *attr, char *buf)
  1986. {
  1987. int x, y, w, h;
  1988. #ifdef CONFIG_POST_PROCESS_MANAGER_PPSCALER
  1989. if(video_scaler_mode){
  1990. x = content_left;
  1991. y = content_top;
  1992. w = content_w;
  1993. h = content_h;
  1994. }else
  1995. #endif
  1996. {
  1997. vpp_get_video_layer_position(&x, &y, &w, &h);
  1998. }
  1999. return snprintf(buf, 40, "%d %d %d %d\n", x, y, x + w - 1, y + h - 1);
  2000. }
  2001. static ssize_t video_axis_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2002. size_t count)
  2003. {
  2004. mutex_lock(&video_module_mutex);
  2005. set_video_window(buf);
  2006. mutex_unlock(&video_module_mutex);
  2007. return strnlen(buf, count);
  2008. }
  2009. static ssize_t video_global_offset_show(struct class *cla, struct class_attribute *attr, char *buf)
  2010. {
  2011. int x, y;
  2012. vpp_get_global_offset(&x, &y);
  2013. return snprintf(buf, 40, "%d %d\n", x, y);
  2014. }
  2015. static ssize_t video_global_offset_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2016. size_t count)
  2017. {
  2018. int parsed[2];
  2019. mutex_lock(&video_module_mutex);
  2020. if (likely(parse_para(buf, 2, parsed) == 2)) {
  2021. vpp_set_global_offset(parsed[0], parsed[1]);
  2022. video_property_changed = true;
  2023. amlog_mask(LOG_MASK_SYSFS,
  2024. "video_offset=>x0:%d,y0:%d\r\n ",
  2025. parsed[0], parsed[1]);
  2026. }
  2027. mutex_unlock(&video_module_mutex);
  2028. return count;
  2029. }
  2030. static ssize_t video_zoom_show(struct class *cla, struct class_attribute *attr, char *buf)
  2031. {
  2032. u32 r = vpp_get_zoom_ratio();
  2033. return snprintf(buf, 40, "%d\n", r);
  2034. }
  2035. static ssize_t video_zoom_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2036. size_t count)
  2037. {
  2038. u32 r;
  2039. char *endp;
  2040. r = simple_strtoul(buf, &endp, 0);
  2041. if ((r <= MAX_ZOOM_RATIO) && (r != vpp_get_zoom_ratio())) {
  2042. vpp_set_zoom_ratio(r);
  2043. video_property_changed = true;
  2044. }
  2045. return count;
  2046. }
  2047. static ssize_t video_screen_mode_show(struct class *cla, struct class_attribute *attr, char *buf)
  2048. {
  2049. const char *wide_str[] = {"normal", "full stretch", "4-3", "16-9", "normal-noscaleup"};
  2050. if (wide_setting < ARRAY_SIZE(wide_str)) {
  2051. return sprintf(buf, "%d:%s\n", wide_setting, wide_str[wide_setting]);
  2052. } else {
  2053. return 0;
  2054. }
  2055. }
  2056. static ssize_t video_screen_mode_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2057. size_t count)
  2058. {
  2059. unsigned long mode;
  2060. char *endp;
  2061. mode = simple_strtol(buf, &endp, 0);
  2062. if ((mode < VIDEO_WIDEOPTION_MAX) && (mode != wide_setting)) {
  2063. wide_setting = mode;
  2064. video_property_changed = true;
  2065. }
  2066. return count;
  2067. }
  2068. static ssize_t video_blackout_policy_show(struct class *cla, struct class_attribute *attr, char *buf)
  2069. {
  2070. return sprintf(buf, "%d\n", blackout);
  2071. }
  2072. static ssize_t video_blackout_policy_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2073. size_t count)
  2074. {
  2075. size_t r;
  2076. r = sscanf(buf, "%d", &blackout);
  2077. if (r != 1) {
  2078. return -EINVAL;
  2079. }
  2080. return count;
  2081. }
  2082. static ssize_t video_brightness_show(struct class *cla, struct class_attribute *attr, char *buf)
  2083. {
  2084. s32 val = (READ_MPEG_REG(VPP_VADJ1_Y) >> 8) & 0x1ff;
  2085. val = (val << 23) >> 23;
  2086. return sprintf(buf, "%d\n", val);
  2087. }
  2088. static ssize_t video_brightness_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2089. size_t count)
  2090. {
  2091. size_t r;
  2092. int val;
  2093. r = sscanf(buf, "%d", &val);
  2094. if ((r != 1) || (val < -255) || (val > 255)) {
  2095. return -EINVAL;
  2096. }
  2097. WRITE_MPEG_REG_BITS(VPP_VADJ1_Y, val, 8, 9);
  2098. WRITE_MPEG_REG(VPP_VADJ_CTRL, VPP_VADJ1_EN);
  2099. return count;
  2100. }
  2101. static ssize_t video_contrast_show(struct class *cla, struct class_attribute *attr, char *buf)
  2102. {
  2103. return sprintf(buf, "%d\n", (int)(READ_MPEG_REG(VPP_VADJ1_Y) & 0xff) - 0x80);
  2104. }
  2105. static ssize_t video_contrast_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2106. size_t count)
  2107. {
  2108. size_t r;
  2109. int val;
  2110. r = sscanf(buf, "%d", &val);
  2111. if ((r != 1) || (val < -127) || (val > 127)) {
  2112. return -EINVAL;
  2113. }
  2114. val += 0x80;
  2115. WRITE_MPEG_REG_BITS(VPP_VADJ1_Y, val, 0, 8);
  2116. WRITE_MPEG_REG(VPP_VADJ_CTRL, VPP_VADJ1_EN);
  2117. return count;
  2118. }
  2119. static ssize_t video_saturation_show(struct class *cla, struct class_attribute *attr, char *buf)
  2120. {
  2121. return sprintf(buf, "%d\n", READ_MPEG_REG(VPP_VADJ1_Y) & 0xff);
  2122. }
  2123. static ssize_t video_saturation_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2124. size_t count)
  2125. {
  2126. size_t r;
  2127. int val;
  2128. r = sscanf(buf, "%d", &val);
  2129. if ((r != 1) || (val < -127) || (val > 127)) {
  2130. return -EINVAL;
  2131. }
  2132. WRITE_MPEG_REG_BITS(VPP_VADJ1_Y, val, 0, 8);
  2133. WRITE_MPEG_REG(VPP_VADJ_CTRL, VPP_VADJ1_EN);
  2134. return count;
  2135. }
  2136. static ssize_t video_disable_show(struct class *cla, struct class_attribute *attr, char *buf)
  2137. {
  2138. return sprintf(buf, "%d\n", disable_video);
  2139. }
  2140. static ssize_t video_disable_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2141. size_t count)
  2142. {
  2143. size_t r;
  2144. int val;
  2145. r = sscanf(buf, "%d", &val);
  2146. if (r != 1) {
  2147. return -EINVAL;
  2148. }
  2149. if (_video_set_disable(val) < 0) {
  2150. return -EINVAL;
  2151. }
  2152. return count;
  2153. }
  2154. static ssize_t frame_addr_show(struct class *cla, struct class_attribute *attr, char *buf)
  2155. {
  2156. canvas_t canvas;
  2157. u32 addr[3];
  2158. if (cur_dispbuf) {
  2159. canvas_read(cur_dispbuf->canvas0Addr & 0xff, &canvas);
  2160. addr[0] = canvas.addr;
  2161. canvas_read((cur_dispbuf->canvas0Addr >> 8) & 0xff, &canvas);
  2162. addr[1] = canvas.addr;
  2163. canvas_read((cur_dispbuf->canvas0Addr >> 16) & 0xff, &canvas);
  2164. addr[2] = canvas.addr;
  2165. return sprintf(buf, "0x%x-0x%x-0x%x\n", addr[0], addr[1], addr[2]);
  2166. }
  2167. return sprintf(buf, "NA\n");
  2168. }
  2169. static ssize_t frame_canvas_width_show(struct class *cla, struct class_attribute *attr, char *buf)
  2170. {
  2171. canvas_t canvas;
  2172. u32 width[3];
  2173. if (cur_dispbuf) {
  2174. canvas_read(cur_dispbuf->canvas0Addr & 0xff, &canvas);
  2175. width[0] = canvas.width;
  2176. canvas_read((cur_dispbuf->canvas0Addr >> 8) & 0xff, &canvas);
  2177. width[1] = canvas.width;
  2178. canvas_read((cur_dispbuf->canvas0Addr >> 16) & 0xff, &canvas);
  2179. width[2] = canvas.width;
  2180. return sprintf(buf, "%d-%d-%d\n", width[0], width[1], width[2]);
  2181. }
  2182. return sprintf(buf, "NA\n");
  2183. }
  2184. static ssize_t frame_canvas_height_show(struct class *cla, struct class_attribute *attr, char *buf)
  2185. {
  2186. canvas_t canvas;
  2187. u32 height[3];
  2188. if (cur_dispbuf) {
  2189. canvas_read(cur_dispbuf->canvas0Addr & 0xff, &canvas);
  2190. height[0] = canvas.height;
  2191. canvas_read((cur_dispbuf->canvas0Addr >> 8) & 0xff, &canvas);
  2192. height[1] = canvas.height;
  2193. canvas_read((cur_dispbuf->canvas0Addr >> 16) & 0xff, &canvas);
  2194. height[2] = canvas.height;
  2195. return sprintf(buf, "%d-%d-%d\n", height[0], height[1], height[2]);
  2196. }
  2197. return sprintf(buf, "NA\n");
  2198. }
  2199. static ssize_t frame_width_show(struct class *cla, struct class_attribute *attr, char *buf)
  2200. {
  2201. if (cur_dispbuf) {
  2202. return sprintf(buf, "%d\n", cur_dispbuf->width);
  2203. }
  2204. return sprintf(buf, "NA\n");
  2205. }
  2206. static ssize_t frame_height_show(struct class *cla, struct class_attribute *attr, char *buf)
  2207. {
  2208. if (cur_dispbuf) {
  2209. return sprintf(buf, "%d\n", cur_dispbuf->height);
  2210. }
  2211. return sprintf(buf, "NA\n");
  2212. }
  2213. static ssize_t frame_format_show(struct class *cla, struct class_attribute *attr, char *buf)
  2214. {
  2215. if (cur_dispbuf) {
  2216. if ((cur_dispbuf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) {
  2217. return sprintf(buf, "interlace-top\n");
  2218. } else if ((cur_dispbuf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_BOTTOM) {
  2219. return sprintf(buf, "interlace-bottom\n");
  2220. } else {
  2221. return sprintf(buf, "progressive\n");
  2222. }
  2223. }
  2224. return sprintf(buf, "NA\n");
  2225. }
  2226. static ssize_t frame_aspect_ratio_show(struct class *cla, struct class_attribute *attr, char *buf)
  2227. {
  2228. if (cur_dispbuf) {
  2229. u32 ar = (cur_dispbuf->ratio_control & DISP_RATIO_ASPECT_RATIO_MASK)
  2230. >> DISP_RATIO_ASPECT_RATIO_BIT;
  2231. if (ar) {
  2232. return sprintf(buf, "0x%x\n", ar);
  2233. } else
  2234. return sprintf(buf, "0x%x\n",
  2235. (cur_dispbuf->width << 8) / cur_dispbuf->height);
  2236. }
  2237. return sprintf(buf, "NA\n");
  2238. }
  2239. static ssize_t frame_rate_show(struct class *cla, struct class_attribute* attr, char* buf)
  2240. {
  2241. u32 cnt = frame_count - last_frame_count;
  2242. u32 time = jiffies;
  2243. u32 tmp = time;
  2244. u32 rate = 0;
  2245. u32 vsync_rate;
  2246. size_t ret;
  2247. time -= last_frame_time;
  2248. last_frame_time = tmp;
  2249. last_frame_count = frame_count;
  2250. rate = 100*cnt * HZ / time;
  2251. vsync_rate = 100*vsync_count * HZ / time;
  2252. ret = sprintf(buf, "VFrame rate is %d.%02dfps, and the panel refresh rate is %d, duration is: %d,vsync_isr/s=%d.%02d,vsync_pts_inc=%d\n",
  2253. rate/100,rate%100, vinfo->sync_duration_num / vinfo->sync_duration_den, time,vsync_rate/100,vsync_rate%100,vsync_pts_inc);
  2254. if((debugflags& DEBUG_FLAG_CALC_PTS_INC) && time>HZ*10 && vsync_rate>0){
  2255. if((vsync_rate*vsync_pts_inc/100)!=90000){
  2256. vsync_pts_inc=90000/(vsync_rate/100);
  2257. }
  2258. }
  2259. vsync_count=0;
  2260. return ret;
  2261. }
  2262. static ssize_t vframe_states_show(struct class *cla, struct class_attribute* attr, char* buf)
  2263. {
  2264. int ret = 0;
  2265. vframe_states_t states;
  2266. if (vf_get_states(&states) == 0) {
  2267. ret += sprintf(buf + ret, "vframe_pool_size=%d\n", states.vf_pool_size);
  2268. ret += sprintf(buf + ret, "vframe buf_free_num=%d\n", states.buf_free_num);
  2269. ret += sprintf(buf + ret, "vframe buf_recycle_num=%d\n", states.buf_recycle_num);
  2270. ret += sprintf(buf + ret, "vframe buf_avail_num=%d\n", states.buf_avail_num);
  2271. } else {
  2272. ret += sprintf(buf + ret, "vframe no states\n");
  2273. }
  2274. return ret;
  2275. }
  2276. static ssize_t device_resolution_show(struct class *cla, struct class_attribute* attr, char* buf)
  2277. {
  2278. const vinfo_t *info = get_current_vinfo();
  2279. if (info != NULL) {
  2280. return sprintf(buf, "%dx%d\n", info->width, info->height);
  2281. } else {
  2282. return sprintf(buf, "0x0\n");
  2283. }
  2284. }
  2285. static ssize_t video_filename_show(struct class *cla, struct class_attribute *attr, char *buf)
  2286. {
  2287. return sprintf(buf, "%s\n", file_name);
  2288. }
  2289. static ssize_t video_filename_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2290. size_t count)
  2291. {
  2292. size_t r;
  2293. r = sscanf(buf, "%s", file_name);
  2294. if (r != 1) {
  2295. return -EINVAL;
  2296. }
  2297. return r;
  2298. }
  2299. static ssize_t video_debugflags_show(struct class *cla, struct class_attribute *attr, char *buf)
  2300. {
  2301. int len=0;
  2302. len+=sprintf(buf+len, "value=%d\n", debugflags);
  2303. len+=sprintf(buf+len, "bit0:playing as fast!\n");
  2304. len+=sprintf(buf+len, "bit1:enable calc pts inc in frame rate show\n");
  2305. return len;
  2306. }
  2307. static ssize_t video_debugflags_store(struct class *cla, struct class_attribute *attr, const char *buf,
  2308. size_t count)
  2309. {
  2310. size_t r;
  2311. int value=-1,seted=1;
  2312. r = sscanf(buf, "%d",&value);
  2313. if(r==1){
  2314. debugflags=value;
  2315. seted=1;
  2316. }else{
  2317. r = sscanf(buf, "0x%x",&value);
  2318. if(r==1){
  2319. debugflags=value;
  2320. seted=1;
  2321. }
  2322. }
  2323. if(seted){
  2324. printk("debugflags changed to %d(%x)\n",debugflags,debugflags);
  2325. return count;
  2326. }else
  2327. return -EINVAL;
  2328. }
  2329. static struct class_attribute amvideo_class_attrs[] = {
  2330. __ATTR(axis,
  2331. S_IRUGO | S_IWUSR,
  2332. video_axis_show,
  2333. video_axis_store),
  2334. __ATTR(global_offset,
  2335. S_IRUGO | S_IWUSR,
  2336. video_global_offset_show,
  2337. video_global_offset_store),
  2338. __ATTR(screen_mode,
  2339. S_IRUGO | S_IWUSR,
  2340. video_screen_mode_show,
  2341. video_screen_mode_store),
  2342. __ATTR(blackout_policy,
  2343. S_IRUGO | S_IWUSR,
  2344. video_blackout_policy_show,
  2345. video_blackout_policy_store),
  2346. __ATTR(disable_video,
  2347. S_IRUGO | S_IWUSR,
  2348. video_disable_show,
  2349. video_disable_store),
  2350. __ATTR(zoom,
  2351. S_IRUGO | S_IWUSR,
  2352. video_zoom_show,
  2353. video_zoom_store),
  2354. __ATTR(brightness,
  2355. S_IRUGO | S_IWUSR,
  2356. video_brightness_show,
  2357. video_brightness_store),
  2358. __ATTR(contrast,
  2359. S_IRUGO | S_IWUSR,
  2360. video_contrast_show,
  2361. video_contrast_store),
  2362. __ATTR(saturation,
  2363. S_IRUGO | S_IWUSR,
  2364. video_saturation_show,
  2365. video_saturation_store),
  2366. __ATTR(file_name,
  2367. S_IRUGO | S_IWUSR,
  2368. video_filename_show,
  2369. video_filename_store),
  2370. __ATTR(debugflags,
  2371. S_IRUGO | S_IWUSR,
  2372. video_debugflags_show,
  2373. video_debugflags_store),
  2374. __ATTR_RO(device_resolution),
  2375. __ATTR_RO(frame_addr),
  2376. __ATTR_RO(frame_canvas_width),
  2377. __ATTR_RO(frame_canvas_height),
  2378. __ATTR_RO(frame_width),
  2379. __ATTR_RO(frame_height),
  2380. __ATTR_RO(frame_format),
  2381. __ATTR_RO(frame_aspect_ratio),
  2382. __ATTR_RO(frame_rate),
  2383. __ATTR_RO(vframe_states),
  2384. __ATTR_NULL
  2385. };
  2386. #ifdef CONFIG_PM
  2387. static int amvideo_class_suspend(struct device *dev, pm_message_t state)
  2388. {
  2389. pm_state.event = state.event;
  2390. if (state.event == PM_EVENT_SUSPEND) {
  2391. pm_state.vpp_misc = READ_MPEG_REG(VPP_MISC);
  2392. DisableVideoLayer();
  2393. msleep(50);
  2394. }
  2395. return 0;
  2396. }
  2397. #ifdef CONFIG_SCREEN_ON_EARLY
  2398. extern void osd_resume_early(void);
  2399. extern void vout_pll_resume_early(void);
  2400. extern void resume_vout_early(void);
  2401. extern int power_key_pressed;
  2402. #endif
  2403. static int amvideo_class_resume(struct device *dev)
  2404. {
  2405. if (pm_state.event == PM_EVENT_SUSPEND) {
  2406. WRITE_MPEG_REG(VPP_MISC, pm_state.vpp_misc);
  2407. pm_state.event = -1;
  2408. }
  2409. #ifdef CONFIG_SCREEN_ON_EARLY
  2410. if(power_key_pressed){
  2411. vout_pll_resume_early();
  2412. osd_resume_early();
  2413. resume_vout_early();
  2414. power_key_pressed = 0;
  2415. }
  2416. #endif
  2417. return 0;
  2418. }
  2419. #endif
  2420. static struct class amvideo_class = {
  2421. .name = AMVIDEO_CLASS_NAME,
  2422. .class_attrs = amvideo_class_attrs,
  2423. #ifdef CONFIG_PM
  2424. .suspend = amvideo_class_suspend,
  2425. .resume = amvideo_class_resume,
  2426. #endif
  2427. };
  2428. static struct device *amvideo_dev;
  2429. int vout_notify_callback(struct notifier_block *block, unsigned long cmd , void *para)
  2430. {
  2431. const vinfo_t *info;
  2432. ulong flags;
  2433. switch (cmd)
  2434. {
  2435. case VOUT_EVENT_MODE_CHANGE:
  2436. info = get_current_vinfo();
  2437. spin_lock_irqsave(&lock, flags);
  2438. vinfo = info;
  2439. /* pre-calculate vsync_pts_inc in 90k unit */
  2440. vsync_pts_inc = 90000 * vinfo->sync_duration_den / vinfo->sync_duration_num;
  2441. spin_unlock_irqrestore(&lock, flags);
  2442. break;
  2443. case VOUT_EVENT_OSD_PREBLEND_ENABLE:
  2444. vpp_set_osd_layer_preblend(para);
  2445. break;
  2446. case VOUT_EVENT_OSD_DISP_AXIS:
  2447. vpp_set_osd_layer_position(para);
  2448. break;
  2449. }
  2450. return 0;
  2451. }
  2452. static struct notifier_block vout_notifier = {
  2453. .notifier_call = vout_notify_callback,
  2454. };
  2455. vframe_t* get_cur_dispbuf(void)
  2456. {
  2457. return cur_dispbuf;
  2458. }
  2459. static void vout_hook(void)
  2460. {
  2461. vout_register_client(&vout_notifier);
  2462. vinfo = get_current_vinfo();
  2463. if (!vinfo) {
  2464. set_current_vmode(VMODE_720P);
  2465. vinfo = get_current_vinfo();
  2466. }
  2467. if (vinfo) {
  2468. vsync_pts_inc = 90000 * vinfo->sync_duration_den / vinfo->sync_duration_num;
  2469. }
  2470. #ifdef CONFIG_AM_VIDEO_LOG
  2471. if (vinfo) {
  2472. amlog_mask(LOG_MASK_VINFO, "vinfo = %p\n", vinfo);
  2473. amlog_mask(LOG_MASK_VINFO, "display platform %s:\n", vinfo->name);
  2474. amlog_mask(LOG_MASK_VINFO, "\tresolution %d x %d\n", vinfo->width, vinfo->height);
  2475. amlog_mask(LOG_MASK_VINFO, "\taspect ratio %d : %d\n", vinfo->aspect_ratio_num, vinfo->aspect_ratio_den);
  2476. amlog_mask(LOG_MASK_VINFO, "\tsync duration %d : %d\n", vinfo->sync_duration_num, vinfo->sync_duration_den);
  2477. }
  2478. #endif
  2479. }
  2480. /*********************************************************/
  2481. static int __init video_early_init(void)
  2482. {
  2483. logo_object_t *init_logo_obj=NULL;
  2484. #ifdef CONFIG_AM_LOGO
  2485. init_logo_obj = get_current_logo_obj();
  2486. #endif
  2487. if(NULL==init_logo_obj || !init_logo_obj->para.loaded)
  2488. {
  2489. WRITE_MPEG_REG_BITS(VPP_OFIFO_SIZE, 0x300,
  2490. VPP_OFIFO_SIZE_BIT, VPP_OFIFO_SIZE_WID);
  2491. CLEAR_MPEG_REG_MASK(VPP_VSC_PHASE_CTRL, VPP_PHASECTL_TYPE_INTERLACE);
  2492. #ifndef CONFIG_FB_AML_TCON
  2493. SET_MPEG_REG_MASK(VPP_MISC, VPP_OUT_SATURATE);
  2494. #endif
  2495. WRITE_MPEG_REG(VPP_HOLD_LINES, 0x08080808);
  2496. }
  2497. return 0;
  2498. }
  2499. static int __init video_init(void)
  2500. {
  2501. int r = 0;
  2502. #ifdef CONFIG_ARCH_MESON1
  2503. ulong clk = clk_get_rate(clk_get_sys("clk_other_pll", NULL));
  2504. #elif !defined(CONFIG_ARCH_MESON3) && !defined(CONFIG_ARCH_MESON6)
  2505. ulong clk = clk_get_rate(clk_get_sys("clk_misc_pll", NULL));
  2506. #endif
  2507. #if !defined(CONFIG_ARCH_MESON3) && !defined(CONFIG_ARCH_MESON6)
  2508. /* MALI clock settings */
  2509. if ((clk <= 750000000) &&
  2510. (clk >= 600000000)) {
  2511. WRITE_CBUS_REG(HHI_MALI_CLK_CNTL,
  2512. (2 << 9) | // select misc pll as clock source
  2513. (1 << 8) | // enable clock gating
  2514. (2 << 0)); // Misc clk / 3
  2515. } else {
  2516. WRITE_CBUS_REG(HHI_MALI_CLK_CNTL,
  2517. (3 << 9) | // select DDR clock as clock source
  2518. (1 << 8) | // enable clock gating
  2519. (1 << 0)); // DDR clk / 2
  2520. }
  2521. #endif
  2522. #ifdef RESERVE_CLR_FRAME
  2523. alloc_keep_buffer();
  2524. #endif
  2525. DisableVideoLayer();
  2526. cur_dispbuf = NULL;
  2527. #ifdef FIQ_VSYNC
  2528. /* enable fiq bridge */
  2529. vsync_fiq_bridge.handle = vsync_bridge_isr;
  2530. vsync_fiq_bridge.key=(u32)vsync_bridge_isr;
  2531. vsync_fiq_bridge.name="vsync_bridge_isr";
  2532. r = register_fiq_bridge_handle(&vsync_fiq_bridge);
  2533. if (r) {
  2534. amlog_level(LOG_LEVEL_ERROR, "video fiq bridge register error.\n");
  2535. r = -ENOENT;
  2536. goto err0;
  2537. }
  2538. #endif
  2539. /* sysfs node creation */
  2540. r = class_register(&amvideo_class);
  2541. if (r) {
  2542. amlog_level(LOG_LEVEL_ERROR, "create video class fail.\n");
  2543. #ifdef FIQ_VSYNC
  2544. free_irq(BRIDGE_IRQ, (void *)video_dev_id);
  2545. #else
  2546. free_irq(INT_VIU_VSYNC, (void *)video_dev_id);
  2547. #endif
  2548. goto err1;
  2549. }
  2550. /* create video device */
  2551. r = register_chrdev(AMVIDEO_MAJOR, "amvideo", &amvideo_fops);
  2552. if (r < 0) {
  2553. amlog_level(LOG_LEVEL_ERROR, "Can't register major for amvideo device\n");
  2554. goto err2;
  2555. }
  2556. amvideo_dev = device_create(&amvideo_class, NULL,
  2557. MKDEV(AMVIDEO_MAJOR, 0), NULL,
  2558. DEVICE_NAME);
  2559. if (IS_ERR(amvideo_dev)) {
  2560. amlog_level(LOG_LEVEL_ERROR, "Can't create amvideo device\n");
  2561. goto err3;
  2562. }
  2563. init_waitqueue_head(&amvideo_trick_wait);
  2564. vout_hook();
  2565. disp_canvas[0] = (disp_canvas_index[2] << 16) | (disp_canvas_index[1] << 8) | disp_canvas_index[0];
  2566. disp_canvas[1] = (disp_canvas_index[5] << 16) | (disp_canvas_index[4] << 8) | disp_canvas_index[3];
  2567. vsync_fiq_up();
  2568. vf_receiver_init(&video_vf_recv, RECEIVER_NAME, &video_vf_receiver, NULL);
  2569. vf_reg_receiver(&video_vf_recv);
  2570. vf_receiver_init(&video4osd_vf_recv, RECEIVER4OSD_NAME, &video4osd_vf_receiver, NULL);
  2571. vf_reg_receiver(&video4osd_vf_recv);
  2572. return (0);
  2573. err3:
  2574. unregister_chrdev(AMVIDEO_MAJOR, DEVICE_NAME);
  2575. err2:
  2576. #ifdef FIQ_VSYNC
  2577. unregister_fiq_bridge_handle(&vsync_fiq_bridge);
  2578. #endif
  2579. err1:
  2580. class_unregister(&amvideo_class);
  2581. #ifdef FIQ_VSYNC
  2582. err0:
  2583. #endif
  2584. return r;
  2585. }
  2586. static void __exit video_exit(void)
  2587. {
  2588. vf_unreg_receiver(&video_vf_recv);
  2589. vf_unreg_receiver(&video4osd_vf_recv);
  2590. DisableVideoLayer();
  2591. vsync_fiq_down();
  2592. device_destroy(&amvideo_class, MKDEV(AMVIDEO_MAJOR, 0));
  2593. unregister_chrdev(AMVIDEO_MAJOR, DEVICE_NAME);
  2594. #ifdef FIQ_VSYNC
  2595. unregister_fiq_bridge_handle(&vsync_fiq_bridge);
  2596. #endif
  2597. class_unregister(&amvideo_class);
  2598. }
  2599. arch_initcall(video_early_init);
  2600. module_init(video_init);
  2601. module_exit(video_exit);
  2602. MODULE_DESCRIPTION("AMLOGIC video output driver");
  2603. MODULE_LICENSE("GPL");
  2604. MODULE_AUTHOR("Tim Yao <timyao@amlogic.com>");