rockchip_drm_vop2.c 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336
  1. // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
  2. /*
  3. * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
  4. * Author: Andy Yan <andy.yan@rock-chips.com>
  5. */
  6. #include <linux/bitfield.h>
  7. #include <linux/clk.h>
  8. #include <linux/component.h>
  9. #include <linux/delay.h>
  10. #include <linux/iopoll.h>
  11. #include <linux/kernel.h>
  12. #include <linux/media-bus-format.h>
  13. #include <linux/mfd/syscon.h>
  14. #include <linux/module.h>
  15. #include <linux/of.h>
  16. #include <linux/of_graph.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/pm_runtime.h>
  19. #include <linux/regmap.h>
  20. #include <linux/swab.h>
  21. #include <drm/drm.h>
  22. #include <drm/drm_atomic.h>
  23. #include <drm/drm_atomic_uapi.h>
  24. #include <drm/drm_blend.h>
  25. #include <drm/drm_crtc.h>
  26. #include <drm/drm_debugfs.h>
  27. #include <drm/drm_flip_work.h>
  28. #include <drm/drm_framebuffer.h>
  29. #include <drm/drm_probe_helper.h>
  30. #include <drm/drm_vblank.h>
  31. #include <uapi/linux/videodev2.h>
  32. #include <dt-bindings/soc/rockchip,vop2.h>
  33. #include "rockchip_drm_gem.h"
  34. #include "rockchip_drm_vop2.h"
  35. #include "rockchip_rgb.h"
  36. /*
  37. * VOP2 architecture
  38. *
  39. +----------+ +-------------+ +-----------+
  40. | Cluster | | Sel 1 from 6| | 1 from 3 |
  41. | window0 | | Layer0 | | RGB |
  42. +----------+ +-------------+ +---------------+ +-------------+ +-----------+
  43. +----------+ +-------------+ |N from 6 layers| | |
  44. | Cluster | | Sel 1 from 6| | Overlay0 +--->| Video Port0 | +-----------+
  45. | window1 | | Layer1 | | | | | | 1 from 3 |
  46. +----------+ +-------------+ +---------------+ +-------------+ | LVDS |
  47. +----------+ +-------------+ +-----------+
  48. | Esmart | | Sel 1 from 6|
  49. | window0 | | Layer2 | +---------------+ +-------------+ +-----------+
  50. +----------+ +-------------+ |N from 6 Layers| | | +--> | 1 from 3 |
  51. +----------+ +-------------+ --------> | Overlay1 +--->| Video Port1 | | MIPI |
  52. | Esmart | | Sel 1 from 6| --------> | | | | +-----------+
  53. | Window1 | | Layer3 | +---------------+ +-------------+
  54. +----------+ +-------------+ +-----------+
  55. +----------+ +-------------+ | 1 from 3 |
  56. | Smart | | Sel 1 from 6| +---------------+ +-------------+ | HDMI |
  57. | Window0 | | Layer4 | |N from 6 Layers| | | +-----------+
  58. +----------+ +-------------+ | Overlay2 +--->| Video Port2 |
  59. +----------+ +-------------+ | | | | +-----------+
  60. | Smart | | Sel 1 from 6| +---------------+ +-------------+ | 1 from 3 |
  61. | Window1 | | Layer5 | | eDP |
  62. +----------+ +-------------+ +-----------+
  63. *
  64. */
  65. enum vop2_data_format {
  66. VOP2_FMT_ARGB8888 = 0,
  67. VOP2_FMT_RGB888,
  68. VOP2_FMT_RGB565,
  69. VOP2_FMT_XRGB101010,
  70. VOP2_FMT_YUV420SP,
  71. VOP2_FMT_YUV422SP,
  72. VOP2_FMT_YUV444SP,
  73. VOP2_FMT_YUYV422 = 8,
  74. VOP2_FMT_YUYV420,
  75. VOP2_FMT_VYUY422,
  76. VOP2_FMT_VYUY420,
  77. VOP2_FMT_YUV420SP_TILE_8x4 = 0x10,
  78. VOP2_FMT_YUV420SP_TILE_16x2,
  79. VOP2_FMT_YUV422SP_TILE_8x4,
  80. VOP2_FMT_YUV422SP_TILE_16x2,
  81. VOP2_FMT_YUV420SP_10,
  82. VOP2_FMT_YUV422SP_10,
  83. VOP2_FMT_YUV444SP_10,
  84. };
  85. enum vop2_afbc_format {
  86. VOP2_AFBC_FMT_RGB565,
  87. VOP2_AFBC_FMT_ARGB2101010 = 2,
  88. VOP2_AFBC_FMT_YUV420_10BIT,
  89. VOP2_AFBC_FMT_RGB888,
  90. VOP2_AFBC_FMT_ARGB8888,
  91. VOP2_AFBC_FMT_YUV420 = 9,
  92. VOP2_AFBC_FMT_YUV422 = 0xb,
  93. VOP2_AFBC_FMT_YUV422_10BIT = 0xe,
  94. VOP2_AFBC_FMT_INVALID = -1,
  95. };
  96. union vop2_alpha_ctrl {
  97. u32 val;
  98. struct {
  99. /* [0:1] */
  100. u32 color_mode:1;
  101. u32 alpha_mode:1;
  102. /* [2:3] */
  103. u32 blend_mode:2;
  104. u32 alpha_cal_mode:1;
  105. /* [5:7] */
  106. u32 factor_mode:3;
  107. /* [8:9] */
  108. u32 alpha_en:1;
  109. u32 src_dst_swap:1;
  110. u32 reserved:6;
  111. /* [16:23] */
  112. u32 glb_alpha:8;
  113. } bits;
  114. };
  115. struct vop2_alpha {
  116. union vop2_alpha_ctrl src_color_ctrl;
  117. union vop2_alpha_ctrl dst_color_ctrl;
  118. union vop2_alpha_ctrl src_alpha_ctrl;
  119. union vop2_alpha_ctrl dst_alpha_ctrl;
  120. };
  121. struct vop2_alpha_config {
  122. bool src_premulti_en;
  123. bool dst_premulti_en;
  124. bool src_pixel_alpha_en;
  125. bool dst_pixel_alpha_en;
  126. u16 src_glb_alpha_value;
  127. u16 dst_glb_alpha_value;
  128. };
  129. struct vop2_win {
  130. struct vop2 *vop2;
  131. struct drm_plane base;
  132. const struct vop2_win_data *data;
  133. struct regmap_field *reg[VOP2_WIN_MAX_REG];
  134. /**
  135. * @win_id: graphic window id, a cluster may be split into two
  136. * graphics windows.
  137. */
  138. u8 win_id;
  139. u8 delay;
  140. u32 offset;
  141. enum drm_plane_type type;
  142. };
  143. struct vop2_video_port {
  144. struct drm_crtc crtc;
  145. struct vop2 *vop2;
  146. struct clk *dclk;
  147. struct clk *dclk_src;
  148. unsigned int id;
  149. const struct vop2_video_port_data *data;
  150. struct completion dsp_hold_completion;
  151. /**
  152. * @win_mask: Bitmask of windows attached to the video port;
  153. */
  154. u32 win_mask;
  155. struct vop2_win *primary_plane;
  156. struct drm_pending_vblank_event *event;
  157. unsigned int nlayers;
  158. };
  159. struct vop2 {
  160. struct device *dev;
  161. struct drm_device *drm;
  162. struct vop2_video_port vps[ROCKCHIP_MAX_CRTC];
  163. const struct vop2_data *data;
  164. /*
  165. * Number of windows that are registered as plane, may be less than the
  166. * total number of hardware windows.
  167. */
  168. u32 registered_num_wins;
  169. void __iomem *regs;
  170. struct regmap *map;
  171. struct regmap *sys_grf;
  172. struct regmap *vop_grf;
  173. struct regmap *vo1_grf;
  174. struct regmap *sys_pmu;
  175. /* physical map length of vop2 register */
  176. u32 len;
  177. void __iomem *lut_regs;
  178. /* protects crtc enable/disable */
  179. struct mutex vop2_lock;
  180. int irq;
  181. /*
  182. * Some global resources are shared between all video ports(crtcs), so
  183. * we need a ref counter here.
  184. */
  185. unsigned int enable_count;
  186. struct clk *hclk;
  187. struct clk *aclk;
  188. struct clk *pclk;
  189. struct clk *pll_hdmiphy0;
  190. /* optional internal rgb encoder */
  191. struct rockchip_rgb *rgb;
  192. /* must be put at the end of the struct */
  193. struct vop2_win win[];
  194. };
  195. #define VOP2_MAX_DCLK_RATE 600000000
  196. #define vop2_output_if_is_hdmi(x) ((x) == ROCKCHIP_VOP2_EP_HDMI0 || \
  197. (x) == ROCKCHIP_VOP2_EP_HDMI1)
  198. #define vop2_output_if_is_dp(x) ((x) == ROCKCHIP_VOP2_EP_DP0 || \
  199. (x) == ROCKCHIP_VOP2_EP_DP1)
  200. #define vop2_output_if_is_edp(x) ((x) == ROCKCHIP_VOP2_EP_EDP0 || \
  201. (x) == ROCKCHIP_VOP2_EP_EDP1)
  202. #define vop2_output_if_is_mipi(x) ((x) == ROCKCHIP_VOP2_EP_MIPI0 || \
  203. (x) == ROCKCHIP_VOP2_EP_MIPI1)
  204. #define vop2_output_if_is_lvds(x) ((x) == ROCKCHIP_VOP2_EP_LVDS0 || \
  205. (x) == ROCKCHIP_VOP2_EP_LVDS1)
  206. #define vop2_output_if_is_dpi(x) ((x) == ROCKCHIP_VOP2_EP_RGB0)
  207. static const struct regmap_config vop2_regmap_config;
  208. static struct vop2_video_port *to_vop2_video_port(struct drm_crtc *crtc)
  209. {
  210. return container_of(crtc, struct vop2_video_port, crtc);
  211. }
  212. static struct vop2_win *to_vop2_win(struct drm_plane *p)
  213. {
  214. return container_of(p, struct vop2_win, base);
  215. }
  216. static void vop2_lock(struct vop2 *vop2)
  217. {
  218. mutex_lock(&vop2->vop2_lock);
  219. }
  220. static void vop2_unlock(struct vop2 *vop2)
  221. {
  222. mutex_unlock(&vop2->vop2_lock);
  223. }
  224. static void vop2_writel(struct vop2 *vop2, u32 offset, u32 v)
  225. {
  226. regmap_write(vop2->map, offset, v);
  227. }
  228. static void vop2_vp_write(struct vop2_video_port *vp, u32 offset, u32 v)
  229. {
  230. regmap_write(vp->vop2->map, vp->data->offset + offset, v);
  231. }
  232. static u32 vop2_readl(struct vop2 *vop2, u32 offset)
  233. {
  234. u32 val;
  235. regmap_read(vop2->map, offset, &val);
  236. return val;
  237. }
  238. static void vop2_win_write(const struct vop2_win *win, unsigned int reg, u32 v)
  239. {
  240. regmap_field_write(win->reg[reg], v);
  241. }
  242. static bool vop2_cluster_window(const struct vop2_win *win)
  243. {
  244. return win->data->feature & WIN_FEATURE_CLUSTER;
  245. }
  246. /*
  247. * Note:
  248. * The write mask function is documented but missing on rk3566/8, writes
  249. * to these bits have no effect. For newer soc(rk3588 and following) the
  250. * write mask is needed for register writes.
  251. *
  252. * GLB_CFG_DONE_EN has no write mask bit.
  253. *
  254. */
  255. static void vop2_cfg_done(struct vop2_video_port *vp)
  256. {
  257. struct vop2 *vop2 = vp->vop2;
  258. u32 val = RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN;
  259. val |= BIT(vp->id) | (BIT(vp->id) << 16);
  260. regmap_set_bits(vop2->map, RK3568_REG_CFG_DONE, val);
  261. }
  262. static void vop2_win_disable(struct vop2_win *win)
  263. {
  264. vop2_win_write(win, VOP2_WIN_ENABLE, 0);
  265. if (vop2_cluster_window(win))
  266. vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 0);
  267. }
  268. static u32 vop2_get_bpp(const struct drm_format_info *format)
  269. {
  270. switch (format->format) {
  271. case DRM_FORMAT_YUV420_8BIT:
  272. return 12;
  273. case DRM_FORMAT_YUV420_10BIT:
  274. return 15;
  275. case DRM_FORMAT_VUY101010:
  276. return 30;
  277. default:
  278. return drm_format_info_bpp(format, 0);
  279. }
  280. }
  281. static enum vop2_data_format vop2_convert_format(u32 format)
  282. {
  283. switch (format) {
  284. case DRM_FORMAT_XRGB2101010:
  285. case DRM_FORMAT_ARGB2101010:
  286. case DRM_FORMAT_XBGR2101010:
  287. case DRM_FORMAT_ABGR2101010:
  288. return VOP2_FMT_XRGB101010;
  289. case DRM_FORMAT_XRGB8888:
  290. case DRM_FORMAT_ARGB8888:
  291. case DRM_FORMAT_XBGR8888:
  292. case DRM_FORMAT_ABGR8888:
  293. return VOP2_FMT_ARGB8888;
  294. case DRM_FORMAT_RGB888:
  295. case DRM_FORMAT_BGR888:
  296. return VOP2_FMT_RGB888;
  297. case DRM_FORMAT_RGB565:
  298. case DRM_FORMAT_BGR565:
  299. return VOP2_FMT_RGB565;
  300. case DRM_FORMAT_NV12:
  301. case DRM_FORMAT_NV21:
  302. case DRM_FORMAT_YUV420_8BIT:
  303. return VOP2_FMT_YUV420SP;
  304. case DRM_FORMAT_NV15:
  305. case DRM_FORMAT_YUV420_10BIT:
  306. return VOP2_FMT_YUV420SP_10;
  307. case DRM_FORMAT_NV16:
  308. case DRM_FORMAT_NV61:
  309. return VOP2_FMT_YUV422SP;
  310. case DRM_FORMAT_NV20:
  311. case DRM_FORMAT_Y210:
  312. return VOP2_FMT_YUV422SP_10;
  313. case DRM_FORMAT_NV24:
  314. case DRM_FORMAT_NV42:
  315. return VOP2_FMT_YUV444SP;
  316. case DRM_FORMAT_NV30:
  317. return VOP2_FMT_YUV444SP_10;
  318. case DRM_FORMAT_YUYV:
  319. case DRM_FORMAT_YVYU:
  320. return VOP2_FMT_VYUY422;
  321. case DRM_FORMAT_VYUY:
  322. case DRM_FORMAT_UYVY:
  323. return VOP2_FMT_YUYV422;
  324. default:
  325. DRM_ERROR("unsupported format[%08x]\n", format);
  326. return -EINVAL;
  327. }
  328. }
  329. static enum vop2_afbc_format vop2_convert_afbc_format(u32 format)
  330. {
  331. switch (format) {
  332. case DRM_FORMAT_XRGB2101010:
  333. case DRM_FORMAT_ARGB2101010:
  334. case DRM_FORMAT_XBGR2101010:
  335. case DRM_FORMAT_ABGR2101010:
  336. return VOP2_AFBC_FMT_ARGB2101010;
  337. case DRM_FORMAT_XRGB8888:
  338. case DRM_FORMAT_ARGB8888:
  339. case DRM_FORMAT_XBGR8888:
  340. case DRM_FORMAT_ABGR8888:
  341. return VOP2_AFBC_FMT_ARGB8888;
  342. case DRM_FORMAT_RGB888:
  343. case DRM_FORMAT_BGR888:
  344. return VOP2_AFBC_FMT_RGB888;
  345. case DRM_FORMAT_RGB565:
  346. case DRM_FORMAT_BGR565:
  347. return VOP2_AFBC_FMT_RGB565;
  348. case DRM_FORMAT_YUV420_8BIT:
  349. return VOP2_AFBC_FMT_YUV420;
  350. case DRM_FORMAT_YUV420_10BIT:
  351. return VOP2_AFBC_FMT_YUV420_10BIT;
  352. case DRM_FORMAT_YVYU:
  353. case DRM_FORMAT_YUYV:
  354. case DRM_FORMAT_VYUY:
  355. case DRM_FORMAT_UYVY:
  356. return VOP2_AFBC_FMT_YUV422;
  357. case DRM_FORMAT_Y210:
  358. return VOP2_AFBC_FMT_YUV422_10BIT;
  359. default:
  360. return VOP2_AFBC_FMT_INVALID;
  361. }
  362. return VOP2_AFBC_FMT_INVALID;
  363. }
  364. static bool vop2_win_rb_swap(u32 format)
  365. {
  366. switch (format) {
  367. case DRM_FORMAT_XBGR2101010:
  368. case DRM_FORMAT_ABGR2101010:
  369. case DRM_FORMAT_XBGR8888:
  370. case DRM_FORMAT_ABGR8888:
  371. case DRM_FORMAT_BGR888:
  372. case DRM_FORMAT_BGR565:
  373. return true;
  374. default:
  375. return false;
  376. }
  377. }
  378. static bool vop2_afbc_uv_swap(u32 format)
  379. {
  380. switch (format) {
  381. case DRM_FORMAT_YUYV:
  382. case DRM_FORMAT_Y210:
  383. case DRM_FORMAT_YUV420_8BIT:
  384. case DRM_FORMAT_YUV420_10BIT:
  385. return true;
  386. default:
  387. return false;
  388. }
  389. }
  390. static bool vop2_win_uv_swap(u32 format)
  391. {
  392. switch (format) {
  393. case DRM_FORMAT_NV12:
  394. case DRM_FORMAT_NV16:
  395. case DRM_FORMAT_NV24:
  396. case DRM_FORMAT_NV15:
  397. case DRM_FORMAT_NV20:
  398. case DRM_FORMAT_NV30:
  399. case DRM_FORMAT_YUYV:
  400. case DRM_FORMAT_UYVY:
  401. return true;
  402. default:
  403. return false;
  404. }
  405. }
  406. static bool vop2_win_dither_up(u32 format)
  407. {
  408. switch (format) {
  409. case DRM_FORMAT_BGR565:
  410. case DRM_FORMAT_RGB565:
  411. return true;
  412. default:
  413. return false;
  414. }
  415. }
  416. static bool vop2_output_uv_swap(u32 bus_format, u32 output_mode)
  417. {
  418. /*
  419. * FIXME:
  420. *
  421. * There is no media type for YUV444 output,
  422. * so when out_mode is AAAA or P888, assume output is YUV444 on
  423. * yuv format.
  424. *
  425. * From H/W testing, YUV444 mode need a rb swap.
  426. */
  427. if (bus_format == MEDIA_BUS_FMT_YVYU8_1X16 ||
  428. bus_format == MEDIA_BUS_FMT_VYUY8_1X16 ||
  429. bus_format == MEDIA_BUS_FMT_YVYU8_2X8 ||
  430. bus_format == MEDIA_BUS_FMT_VYUY8_2X8 ||
  431. ((bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
  432. bus_format == MEDIA_BUS_FMT_YUV10_1X30) &&
  433. (output_mode == ROCKCHIP_OUT_MODE_AAAA ||
  434. output_mode == ROCKCHIP_OUT_MODE_P888)))
  435. return true;
  436. else
  437. return false;
  438. }
  439. static bool vop2_output_rg_swap(struct vop2 *vop2, u32 bus_format)
  440. {
  441. if (vop2->data->soc_id == 3588) {
  442. if (bus_format == MEDIA_BUS_FMT_YUV8_1X24 ||
  443. bus_format == MEDIA_BUS_FMT_YUV10_1X30)
  444. return true;
  445. }
  446. return false;
  447. }
  448. static bool is_yuv_output(u32 bus_format)
  449. {
  450. switch (bus_format) {
  451. case MEDIA_BUS_FMT_YUV8_1X24:
  452. case MEDIA_BUS_FMT_YUV10_1X30:
  453. case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
  454. case MEDIA_BUS_FMT_UYYVYY10_0_5X30:
  455. case MEDIA_BUS_FMT_YUYV8_2X8:
  456. case MEDIA_BUS_FMT_YVYU8_2X8:
  457. case MEDIA_BUS_FMT_UYVY8_2X8:
  458. case MEDIA_BUS_FMT_VYUY8_2X8:
  459. case MEDIA_BUS_FMT_YUYV8_1X16:
  460. case MEDIA_BUS_FMT_YVYU8_1X16:
  461. case MEDIA_BUS_FMT_UYVY8_1X16:
  462. case MEDIA_BUS_FMT_VYUY8_1X16:
  463. return true;
  464. default:
  465. return false;
  466. }
  467. }
  468. static bool rockchip_afbc(struct drm_plane *plane, u64 modifier)
  469. {
  470. int i;
  471. if (modifier == DRM_FORMAT_MOD_LINEAR)
  472. return false;
  473. for (i = 0 ; i < plane->modifier_count; i++)
  474. if (plane->modifiers[i] == modifier)
  475. return true;
  476. return false;
  477. }
  478. static bool rockchip_vop2_mod_supported(struct drm_plane *plane, u32 format,
  479. u64 modifier)
  480. {
  481. struct vop2_win *win = to_vop2_win(plane);
  482. struct vop2 *vop2 = win->vop2;
  483. if (modifier == DRM_FORMAT_MOD_INVALID)
  484. return false;
  485. if (vop2->data->soc_id == 3568 || vop2->data->soc_id == 3566) {
  486. if (vop2_cluster_window(win)) {
  487. if (modifier == DRM_FORMAT_MOD_LINEAR) {
  488. drm_dbg_kms(vop2->drm,
  489. "Cluster window only supports format with afbc\n");
  490. return false;
  491. }
  492. }
  493. }
  494. if (format == DRM_FORMAT_XRGB2101010 || format == DRM_FORMAT_XBGR2101010) {
  495. if (vop2->data->soc_id == 3588) {
  496. if (!rockchip_afbc(plane, modifier)) {
  497. drm_dbg_kms(vop2->drm, "Only support 32 bpp format with afbc\n");
  498. return false;
  499. }
  500. }
  501. }
  502. if (modifier == DRM_FORMAT_MOD_LINEAR)
  503. return true;
  504. if (!rockchip_afbc(plane, modifier)) {
  505. drm_dbg_kms(vop2->drm, "Unsupported format modifier 0x%llx\n",
  506. modifier);
  507. return false;
  508. }
  509. return vop2_convert_afbc_format(format) >= 0;
  510. }
  511. /*
  512. * 0: Full mode, 16 lines for one tail
  513. * 1: half block mode, 8 lines one tail
  514. */
  515. static bool vop2_half_block_enable(struct drm_plane_state *pstate)
  516. {
  517. if (pstate->rotation & (DRM_MODE_ROTATE_270 | DRM_MODE_ROTATE_90))
  518. return false;
  519. else
  520. return true;
  521. }
  522. static u32 vop2_afbc_transform_offset(struct drm_plane_state *pstate,
  523. bool afbc_half_block_en)
  524. {
  525. struct drm_rect *src = &pstate->src;
  526. struct drm_framebuffer *fb = pstate->fb;
  527. u32 bpp = vop2_get_bpp(fb->format);
  528. u32 vir_width = (fb->pitches[0] << 3) / bpp;
  529. u32 width = drm_rect_width(src) >> 16;
  530. u32 height = drm_rect_height(src) >> 16;
  531. u32 act_xoffset = src->x1 >> 16;
  532. u32 act_yoffset = src->y1 >> 16;
  533. u32 align16_crop = 0;
  534. u32 align64_crop = 0;
  535. u32 height_tmp;
  536. u8 tx, ty;
  537. u8 bottom_crop_line_num = 0;
  538. /* 16 pixel align */
  539. if (height & 0xf)
  540. align16_crop = 16 - (height & 0xf);
  541. height_tmp = height + align16_crop;
  542. /* 64 pixel align */
  543. if (height_tmp & 0x3f)
  544. align64_crop = 64 - (height_tmp & 0x3f);
  545. bottom_crop_line_num = align16_crop + align64_crop;
  546. switch (pstate->rotation &
  547. (DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y |
  548. DRM_MODE_ROTATE_90 | DRM_MODE_ROTATE_270)) {
  549. case DRM_MODE_REFLECT_X | DRM_MODE_REFLECT_Y:
  550. tx = 16 - ((act_xoffset + width) & 0xf);
  551. ty = bottom_crop_line_num - act_yoffset;
  552. break;
  553. case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90:
  554. tx = bottom_crop_line_num - act_yoffset;
  555. ty = vir_width - width - act_xoffset;
  556. break;
  557. case DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_270:
  558. tx = act_yoffset;
  559. ty = act_xoffset;
  560. break;
  561. case DRM_MODE_REFLECT_X:
  562. tx = 16 - ((act_xoffset + width) & 0xf);
  563. ty = act_yoffset;
  564. break;
  565. case DRM_MODE_REFLECT_Y:
  566. tx = act_xoffset;
  567. ty = bottom_crop_line_num - act_yoffset;
  568. break;
  569. case DRM_MODE_ROTATE_90:
  570. tx = bottom_crop_line_num - act_yoffset;
  571. ty = act_xoffset;
  572. break;
  573. case DRM_MODE_ROTATE_270:
  574. tx = act_yoffset;
  575. ty = vir_width - width - act_xoffset;
  576. break;
  577. case 0:
  578. tx = act_xoffset;
  579. ty = act_yoffset;
  580. break;
  581. }
  582. if (afbc_half_block_en)
  583. ty &= 0x7f;
  584. #define TRANSFORM_XOFFSET GENMASK(7, 0)
  585. #define TRANSFORM_YOFFSET GENMASK(23, 16)
  586. return FIELD_PREP(TRANSFORM_XOFFSET, tx) |
  587. FIELD_PREP(TRANSFORM_YOFFSET, ty);
  588. }
  589. /*
  590. * A Cluster window has 2048 x 16 line buffer, which can
  591. * works at 2048 x 16(Full) or 4096 x 8 (Half) mode.
  592. * for Cluster_lb_mode register:
  593. * 0: half mode, for plane input width range 2048 ~ 4096
  594. * 1: half mode, for cluster work at 2 * 2048 plane mode
  595. * 2: half mode, for rotate_90/270 mode
  596. *
  597. */
  598. static int vop2_get_cluster_lb_mode(struct vop2_win *win,
  599. struct drm_plane_state *pstate)
  600. {
  601. if ((pstate->rotation & DRM_MODE_ROTATE_270) ||
  602. (pstate->rotation & DRM_MODE_ROTATE_90))
  603. return 2;
  604. else
  605. return 0;
  606. }
  607. static u16 vop2_scale_factor(u32 src, u32 dst)
  608. {
  609. u32 fac;
  610. int shift;
  611. if (src == dst)
  612. return 0;
  613. if (dst < 2)
  614. return U16_MAX;
  615. if (src < 2)
  616. return 0;
  617. if (src > dst)
  618. shift = 12;
  619. else
  620. shift = 16;
  621. src--;
  622. dst--;
  623. fac = DIV_ROUND_UP(src << shift, dst) - 1;
  624. if (fac > U16_MAX)
  625. return U16_MAX;
  626. return fac;
  627. }
  628. static void vop2_setup_scale(struct vop2 *vop2, const struct vop2_win *win,
  629. u32 src_w, u32 src_h, u32 dst_w,
  630. u32 dst_h, u32 pixel_format)
  631. {
  632. const struct drm_format_info *info;
  633. u16 hor_scl_mode, ver_scl_mode;
  634. u16 hscl_filter_mode, vscl_filter_mode;
  635. uint16_t cbcr_src_w = src_w;
  636. uint16_t cbcr_src_h = src_h;
  637. u8 gt2 = 0;
  638. u8 gt4 = 0;
  639. u32 val;
  640. info = drm_format_info(pixel_format);
  641. if (src_h >= (4 * dst_h)) {
  642. gt4 = 1;
  643. src_h >>= 2;
  644. } else if (src_h >= (2 * dst_h)) {
  645. gt2 = 1;
  646. src_h >>= 1;
  647. }
  648. hor_scl_mode = scl_get_scl_mode(src_w, dst_w);
  649. ver_scl_mode = scl_get_scl_mode(src_h, dst_h);
  650. if (hor_scl_mode == SCALE_UP)
  651. hscl_filter_mode = VOP2_SCALE_UP_BIC;
  652. else
  653. hscl_filter_mode = VOP2_SCALE_DOWN_BIL;
  654. if (ver_scl_mode == SCALE_UP)
  655. vscl_filter_mode = VOP2_SCALE_UP_BIL;
  656. else
  657. vscl_filter_mode = VOP2_SCALE_DOWN_BIL;
  658. /*
  659. * RK3568 VOP Esmart/Smart dsp_w should be even pixel
  660. * at scale down mode
  661. */
  662. if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
  663. if ((hor_scl_mode == SCALE_DOWN) && (dst_w & 0x1)) {
  664. drm_dbg(vop2->drm, "%s dst_w[%d] should align as 2 pixel\n",
  665. win->data->name, dst_w);
  666. dst_w++;
  667. }
  668. }
  669. val = vop2_scale_factor(src_w, dst_w);
  670. vop2_win_write(win, VOP2_WIN_SCALE_YRGB_X, val);
  671. val = vop2_scale_factor(src_h, dst_h);
  672. vop2_win_write(win, VOP2_WIN_SCALE_YRGB_Y, val);
  673. vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT4, gt4);
  674. vop2_win_write(win, VOP2_WIN_VSD_YRGB_GT2, gt2);
  675. vop2_win_write(win, VOP2_WIN_YRGB_HOR_SCL_MODE, hor_scl_mode);
  676. vop2_win_write(win, VOP2_WIN_YRGB_VER_SCL_MODE, ver_scl_mode);
  677. if (vop2_cluster_window(win))
  678. return;
  679. vop2_win_write(win, VOP2_WIN_YRGB_HSCL_FILTER_MODE, hscl_filter_mode);
  680. vop2_win_write(win, VOP2_WIN_YRGB_VSCL_FILTER_MODE, vscl_filter_mode);
  681. if (info->is_yuv) {
  682. cbcr_src_w /= info->hsub;
  683. cbcr_src_h /= info->vsub;
  684. gt4 = 0;
  685. gt2 = 0;
  686. if (cbcr_src_h >= (4 * dst_h)) {
  687. gt4 = 1;
  688. cbcr_src_h >>= 2;
  689. } else if (cbcr_src_h >= (2 * dst_h)) {
  690. gt2 = 1;
  691. cbcr_src_h >>= 1;
  692. }
  693. hor_scl_mode = scl_get_scl_mode(cbcr_src_w, dst_w);
  694. ver_scl_mode = scl_get_scl_mode(cbcr_src_h, dst_h);
  695. val = vop2_scale_factor(cbcr_src_w, dst_w);
  696. vop2_win_write(win, VOP2_WIN_SCALE_CBCR_X, val);
  697. val = vop2_scale_factor(cbcr_src_h, dst_h);
  698. vop2_win_write(win, VOP2_WIN_SCALE_CBCR_Y, val);
  699. vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT4, gt4);
  700. vop2_win_write(win, VOP2_WIN_VSD_CBCR_GT2, gt2);
  701. vop2_win_write(win, VOP2_WIN_CBCR_HOR_SCL_MODE, hor_scl_mode);
  702. vop2_win_write(win, VOP2_WIN_CBCR_VER_SCL_MODE, ver_scl_mode);
  703. vop2_win_write(win, VOP2_WIN_CBCR_HSCL_FILTER_MODE, hscl_filter_mode);
  704. vop2_win_write(win, VOP2_WIN_CBCR_VSCL_FILTER_MODE, vscl_filter_mode);
  705. }
  706. }
  707. static int vop2_convert_csc_mode(int csc_mode)
  708. {
  709. switch (csc_mode) {
  710. case V4L2_COLORSPACE_SMPTE170M:
  711. case V4L2_COLORSPACE_470_SYSTEM_M:
  712. case V4L2_COLORSPACE_470_SYSTEM_BG:
  713. return CSC_BT601L;
  714. case V4L2_COLORSPACE_REC709:
  715. case V4L2_COLORSPACE_SMPTE240M:
  716. case V4L2_COLORSPACE_DEFAULT:
  717. return CSC_BT709L;
  718. case V4L2_COLORSPACE_JPEG:
  719. return CSC_BT601F;
  720. case V4L2_COLORSPACE_BT2020:
  721. return CSC_BT2020;
  722. default:
  723. return CSC_BT709L;
  724. }
  725. }
  726. /*
  727. * colorspace path:
  728. * Input Win csc Output
  729. * 1. YUV(2020) --> Y2R->2020To709->R2Y --> YUV_OUTPUT(601/709)
  730. * RGB --> R2Y __/
  731. *
  732. * 2. YUV(2020) --> bypasss --> YUV_OUTPUT(2020)
  733. * RGB --> 709To2020->R2Y __/
  734. *
  735. * 3. YUV(2020) --> Y2R->2020To709 --> RGB_OUTPUT(709)
  736. * RGB --> R2Y __/
  737. *
  738. * 4. YUV(601/709)-> Y2R->709To2020->R2Y --> YUV_OUTPUT(2020)
  739. * RGB --> 709To2020->R2Y __/
  740. *
  741. * 5. YUV(601/709)-> bypass --> YUV_OUTPUT(709)
  742. * RGB --> R2Y __/
  743. *
  744. * 6. YUV(601/709)-> bypass --> YUV_OUTPUT(601)
  745. * RGB --> R2Y(601) __/
  746. *
  747. * 7. YUV --> Y2R(709) --> RGB_OUTPUT(709)
  748. * RGB --> bypass __/
  749. *
  750. * 8. RGB --> 709To2020->R2Y --> YUV_OUTPUT(2020)
  751. *
  752. * 9. RGB --> R2Y(709) --> YUV_OUTPUT(709)
  753. *
  754. * 10. RGB --> R2Y(601) --> YUV_OUTPUT(601)
  755. *
  756. * 11. RGB --> bypass --> RGB_OUTPUT(709)
  757. */
  758. static void vop2_setup_csc_mode(struct vop2_video_port *vp,
  759. struct vop2_win *win,
  760. struct drm_plane_state *pstate)
  761. {
  762. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
  763. int is_input_yuv = pstate->fb->format->is_yuv;
  764. int is_output_yuv = is_yuv_output(vcstate->bus_format);
  765. int input_csc = V4L2_COLORSPACE_DEFAULT;
  766. int output_csc = vcstate->color_space;
  767. bool r2y_en, y2r_en;
  768. int csc_mode;
  769. if (is_input_yuv && !is_output_yuv) {
  770. y2r_en = true;
  771. r2y_en = false;
  772. csc_mode = vop2_convert_csc_mode(input_csc);
  773. } else if (!is_input_yuv && is_output_yuv) {
  774. y2r_en = false;
  775. r2y_en = true;
  776. csc_mode = vop2_convert_csc_mode(output_csc);
  777. } else {
  778. y2r_en = false;
  779. r2y_en = false;
  780. csc_mode = false;
  781. }
  782. vop2_win_write(win, VOP2_WIN_Y2R_EN, y2r_en);
  783. vop2_win_write(win, VOP2_WIN_R2Y_EN, r2y_en);
  784. vop2_win_write(win, VOP2_WIN_CSC_MODE, csc_mode);
  785. }
  786. static void vop2_crtc_enable_irq(struct vop2_video_port *vp, u32 irq)
  787. {
  788. struct vop2 *vop2 = vp->vop2;
  789. vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irq << 16 | irq);
  790. vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16 | irq);
  791. }
  792. static void vop2_crtc_disable_irq(struct vop2_video_port *vp, u32 irq)
  793. {
  794. struct vop2 *vop2 = vp->vop2;
  795. vop2_writel(vop2, RK3568_VP_INT_EN(vp->id), irq << 16);
  796. }
  797. static int vop2_core_clks_prepare_enable(struct vop2 *vop2)
  798. {
  799. int ret;
  800. ret = clk_prepare_enable(vop2->hclk);
  801. if (ret < 0) {
  802. drm_err(vop2->drm, "failed to enable hclk - %d\n", ret);
  803. return ret;
  804. }
  805. ret = clk_prepare_enable(vop2->aclk);
  806. if (ret < 0) {
  807. drm_err(vop2->drm, "failed to enable aclk - %d\n", ret);
  808. goto err;
  809. }
  810. ret = clk_prepare_enable(vop2->pclk);
  811. if (ret < 0) {
  812. drm_err(vop2->drm, "failed to enable pclk - %d\n", ret);
  813. goto err1;
  814. }
  815. return 0;
  816. err1:
  817. clk_disable_unprepare(vop2->aclk);
  818. err:
  819. clk_disable_unprepare(vop2->hclk);
  820. return ret;
  821. }
  822. static void rk3588_vop2_power_domain_enable_all(struct vop2 *vop2)
  823. {
  824. u32 pd;
  825. pd = vop2_readl(vop2, RK3588_SYS_PD_CTRL);
  826. pd &= ~(VOP2_PD_CLUSTER0 | VOP2_PD_CLUSTER1 | VOP2_PD_CLUSTER2 |
  827. VOP2_PD_CLUSTER3 | VOP2_PD_ESMART);
  828. vop2_writel(vop2, RK3588_SYS_PD_CTRL, pd);
  829. }
  830. static void vop2_enable(struct vop2 *vop2)
  831. {
  832. int ret;
  833. ret = pm_runtime_resume_and_get(vop2->dev);
  834. if (ret < 0) {
  835. drm_err(vop2->drm, "failed to get pm runtime: %d\n", ret);
  836. return;
  837. }
  838. ret = vop2_core_clks_prepare_enable(vop2);
  839. if (ret) {
  840. pm_runtime_put_sync(vop2->dev);
  841. return;
  842. }
  843. ret = rockchip_drm_dma_attach_device(vop2->drm, vop2->dev);
  844. if (ret) {
  845. drm_err(vop2->drm, "failed to attach dma mapping, %d\n", ret);
  846. return;
  847. }
  848. if (vop2->data->soc_id == 3566)
  849. vop2_writel(vop2, RK3568_OTP_WIN_EN, 1);
  850. if (vop2->data->soc_id == 3588)
  851. rk3588_vop2_power_domain_enable_all(vop2);
  852. vop2_writel(vop2, RK3568_REG_CFG_DONE, RK3568_REG_CFG_DONE__GLB_CFG_DONE_EN);
  853. /*
  854. * Disable auto gating, this is a workaround to
  855. * avoid display image shift when a window enabled.
  856. */
  857. regmap_clear_bits(vop2->map, RK3568_SYS_AUTO_GATING_CTRL,
  858. RK3568_SYS_AUTO_GATING_CTRL__AUTO_GATING_EN);
  859. vop2_writel(vop2, RK3568_SYS0_INT_CLR,
  860. VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
  861. vop2_writel(vop2, RK3568_SYS0_INT_EN,
  862. VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
  863. vop2_writel(vop2, RK3568_SYS1_INT_CLR,
  864. VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
  865. vop2_writel(vop2, RK3568_SYS1_INT_EN,
  866. VOP2_INT_BUS_ERRPR << 16 | VOP2_INT_BUS_ERRPR);
  867. }
  868. static void vop2_disable(struct vop2 *vop2)
  869. {
  870. rockchip_drm_dma_detach_device(vop2->drm, vop2->dev);
  871. pm_runtime_put_sync(vop2->dev);
  872. regcache_drop_region(vop2->map, 0, vop2_regmap_config.max_register);
  873. clk_disable_unprepare(vop2->pclk);
  874. clk_disable_unprepare(vop2->aclk);
  875. clk_disable_unprepare(vop2->hclk);
  876. }
  877. static void vop2_crtc_atomic_disable(struct drm_crtc *crtc,
  878. struct drm_atomic_state *state)
  879. {
  880. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  881. struct vop2 *vop2 = vp->vop2;
  882. struct drm_crtc_state *old_crtc_state;
  883. int ret;
  884. vop2_lock(vop2);
  885. old_crtc_state = drm_atomic_get_old_crtc_state(state, crtc);
  886. drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false);
  887. drm_crtc_vblank_off(crtc);
  888. /*
  889. * Vop standby will take effect at end of current frame,
  890. * if dsp hold valid irq happen, it means standby complete.
  891. *
  892. * we must wait standby complete when we want to disable aclk,
  893. * if not, memory bus maybe dead.
  894. */
  895. reinit_completion(&vp->dsp_hold_completion);
  896. vop2_crtc_enable_irq(vp, VP_INT_DSP_HOLD_VALID);
  897. vop2_vp_write(vp, RK3568_VP_DSP_CTRL, RK3568_VP_DSP_CTRL__STANDBY);
  898. ret = wait_for_completion_timeout(&vp->dsp_hold_completion,
  899. msecs_to_jiffies(50));
  900. if (!ret)
  901. drm_info(vop2->drm, "wait for vp%d dsp_hold timeout\n", vp->id);
  902. vop2_crtc_disable_irq(vp, VP_INT_DSP_HOLD_VALID);
  903. if (vp->dclk_src)
  904. clk_set_parent(vp->dclk, vp->dclk_src);
  905. clk_disable_unprepare(vp->dclk);
  906. vop2->enable_count--;
  907. if (!vop2->enable_count)
  908. vop2_disable(vop2);
  909. vop2_unlock(vop2);
  910. if (crtc->state->event && !crtc->state->active) {
  911. spin_lock_irq(&crtc->dev->event_lock);
  912. drm_crtc_send_vblank_event(crtc, crtc->state->event);
  913. spin_unlock_irq(&crtc->dev->event_lock);
  914. crtc->state->event = NULL;
  915. }
  916. }
  917. static int vop2_plane_atomic_check(struct drm_plane *plane,
  918. struct drm_atomic_state *astate)
  919. {
  920. struct drm_plane_state *pstate = drm_atomic_get_new_plane_state(astate, plane);
  921. struct drm_framebuffer *fb = pstate->fb;
  922. struct drm_crtc *crtc = pstate->crtc;
  923. struct drm_crtc_state *cstate;
  924. struct vop2_video_port *vp;
  925. struct vop2 *vop2;
  926. const struct vop2_data *vop2_data;
  927. struct drm_rect *dest = &pstate->dst;
  928. struct drm_rect *src = &pstate->src;
  929. int min_scale = FRAC_16_16(1, 8);
  930. int max_scale = FRAC_16_16(8, 1);
  931. int format;
  932. int ret;
  933. if (!crtc)
  934. return 0;
  935. vp = to_vop2_video_port(crtc);
  936. vop2 = vp->vop2;
  937. vop2_data = vop2->data;
  938. cstate = drm_atomic_get_existing_crtc_state(pstate->state, crtc);
  939. if (WARN_ON(!cstate))
  940. return -EINVAL;
  941. ret = drm_atomic_helper_check_plane_state(pstate, cstate,
  942. min_scale, max_scale,
  943. true, true);
  944. if (ret)
  945. return ret;
  946. if (!pstate->visible)
  947. return 0;
  948. format = vop2_convert_format(fb->format->format);
  949. if (format < 0)
  950. return format;
  951. if (drm_rect_width(src) >> 16 < 4 || drm_rect_height(src) >> 16 < 4 ||
  952. drm_rect_width(dest) < 4 || drm_rect_height(dest) < 4) {
  953. drm_err(vop2->drm, "Invalid size: %dx%d->%dx%d, min size is 4x4\n",
  954. drm_rect_width(src) >> 16, drm_rect_height(src) >> 16,
  955. drm_rect_width(dest), drm_rect_height(dest));
  956. pstate->visible = false;
  957. return 0;
  958. }
  959. if (drm_rect_width(src) >> 16 > vop2_data->max_input.width ||
  960. drm_rect_height(src) >> 16 > vop2_data->max_input.height) {
  961. drm_err(vop2->drm, "Invalid source: %dx%d. max input: %dx%d\n",
  962. drm_rect_width(src) >> 16,
  963. drm_rect_height(src) >> 16,
  964. vop2_data->max_input.width,
  965. vop2_data->max_input.height);
  966. return -EINVAL;
  967. }
  968. /*
  969. * Src.x1 can be odd when do clip, but yuv plane start point
  970. * need align with 2 pixel.
  971. */
  972. if (fb->format->is_yuv && ((pstate->src.x1 >> 16) % 2)) {
  973. drm_err(vop2->drm, "Invalid Source: Yuv format not support odd xpos\n");
  974. return -EINVAL;
  975. }
  976. return 0;
  977. }
  978. static void vop2_plane_atomic_disable(struct drm_plane *plane,
  979. struct drm_atomic_state *state)
  980. {
  981. struct drm_plane_state *old_pstate = NULL;
  982. struct vop2_win *win = to_vop2_win(plane);
  983. struct vop2 *vop2 = win->vop2;
  984. drm_dbg(vop2->drm, "%s disable\n", win->data->name);
  985. if (state)
  986. old_pstate = drm_atomic_get_old_plane_state(state, plane);
  987. if (old_pstate && !old_pstate->crtc)
  988. return;
  989. vop2_win_disable(win);
  990. vop2_win_write(win, VOP2_WIN_YUV_CLIP, 0);
  991. }
  992. /*
  993. * The color key is 10 bit, so all format should
  994. * convert to 10 bit here.
  995. */
  996. static void vop2_plane_setup_color_key(struct drm_plane *plane, u32 color_key)
  997. {
  998. struct drm_plane_state *pstate = plane->state;
  999. struct drm_framebuffer *fb = pstate->fb;
  1000. struct vop2_win *win = to_vop2_win(plane);
  1001. u32 color_key_en = 0;
  1002. u32 r = 0;
  1003. u32 g = 0;
  1004. u32 b = 0;
  1005. if (!(color_key & VOP2_COLOR_KEY_MASK) || fb->format->is_yuv) {
  1006. vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, 0);
  1007. return;
  1008. }
  1009. switch (fb->format->format) {
  1010. case DRM_FORMAT_RGB565:
  1011. case DRM_FORMAT_BGR565:
  1012. r = (color_key & 0xf800) >> 11;
  1013. g = (color_key & 0x7e0) >> 5;
  1014. b = (color_key & 0x1f);
  1015. r <<= 5;
  1016. g <<= 4;
  1017. b <<= 5;
  1018. color_key_en = 1;
  1019. break;
  1020. case DRM_FORMAT_XRGB8888:
  1021. case DRM_FORMAT_ARGB8888:
  1022. case DRM_FORMAT_XBGR8888:
  1023. case DRM_FORMAT_ABGR8888:
  1024. case DRM_FORMAT_RGB888:
  1025. case DRM_FORMAT_BGR888:
  1026. r = (color_key & 0xff0000) >> 16;
  1027. g = (color_key & 0xff00) >> 8;
  1028. b = (color_key & 0xff);
  1029. r <<= 2;
  1030. g <<= 2;
  1031. b <<= 2;
  1032. color_key_en = 1;
  1033. break;
  1034. }
  1035. vop2_win_write(win, VOP2_WIN_COLOR_KEY_EN, color_key_en);
  1036. vop2_win_write(win, VOP2_WIN_COLOR_KEY, (r << 20) | (g << 10) | b);
  1037. }
  1038. static void vop2_plane_atomic_update(struct drm_plane *plane,
  1039. struct drm_atomic_state *state)
  1040. {
  1041. struct drm_plane_state *pstate = plane->state;
  1042. struct drm_crtc *crtc = pstate->crtc;
  1043. struct vop2_win *win = to_vop2_win(plane);
  1044. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1045. struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
  1046. struct vop2 *vop2 = win->vop2;
  1047. struct drm_framebuffer *fb = pstate->fb;
  1048. u32 bpp = vop2_get_bpp(fb->format);
  1049. u32 actual_w, actual_h, dsp_w, dsp_h;
  1050. u32 act_info, dsp_info;
  1051. u32 format;
  1052. u32 afbc_format;
  1053. u32 rb_swap;
  1054. u32 uv_swap;
  1055. struct drm_rect *src = &pstate->src;
  1056. struct drm_rect *dest = &pstate->dst;
  1057. u32 afbc_tile_num;
  1058. u32 transform_offset;
  1059. bool dither_up;
  1060. bool xmirror = pstate->rotation & DRM_MODE_REFLECT_X ? true : false;
  1061. bool ymirror = pstate->rotation & DRM_MODE_REFLECT_Y ? true : false;
  1062. bool rotate_270 = pstate->rotation & DRM_MODE_ROTATE_270;
  1063. bool rotate_90 = pstate->rotation & DRM_MODE_ROTATE_90;
  1064. struct rockchip_gem_object *rk_obj;
  1065. unsigned long offset;
  1066. bool half_block_en;
  1067. bool afbc_en;
  1068. dma_addr_t yrgb_mst;
  1069. dma_addr_t uv_mst;
  1070. /*
  1071. * can't update plane when vop2 is disabled.
  1072. */
  1073. if (WARN_ON(!crtc))
  1074. return;
  1075. if (!pstate->visible) {
  1076. vop2_plane_atomic_disable(plane, state);
  1077. return;
  1078. }
  1079. afbc_en = rockchip_afbc(plane, fb->modifier);
  1080. offset = (src->x1 >> 16) * fb->format->cpp[0];
  1081. /*
  1082. * AFBC HDR_PTR must set to the zero offset of the framebuffer.
  1083. */
  1084. if (afbc_en)
  1085. offset = 0;
  1086. else if (pstate->rotation & DRM_MODE_REFLECT_Y)
  1087. offset += ((src->y2 >> 16) - 1) * fb->pitches[0];
  1088. else
  1089. offset += (src->y1 >> 16) * fb->pitches[0];
  1090. rk_obj = to_rockchip_obj(fb->obj[0]);
  1091. yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
  1092. if (fb->format->is_yuv) {
  1093. int hsub = fb->format->hsub;
  1094. int vsub = fb->format->vsub;
  1095. offset = (src->x1 >> 16) * fb->format->cpp[1] / hsub;
  1096. offset += (src->y1 >> 16) * fb->pitches[1] / vsub;
  1097. if ((pstate->rotation & DRM_MODE_REFLECT_Y) && !afbc_en)
  1098. offset += fb->pitches[1] * ((pstate->src_h >> 16) - 2) / vsub;
  1099. rk_obj = to_rockchip_obj(fb->obj[0]);
  1100. uv_mst = rk_obj->dma_addr + offset + fb->offsets[1];
  1101. }
  1102. actual_w = drm_rect_width(src) >> 16;
  1103. actual_h = drm_rect_height(src) >> 16;
  1104. dsp_w = drm_rect_width(dest);
  1105. if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
  1106. drm_err(vop2->drm, "vp%d %s dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
  1107. vp->id, win->data->name, dest->x1, dsp_w, adjusted_mode->hdisplay);
  1108. dsp_w = adjusted_mode->hdisplay - dest->x1;
  1109. if (dsp_w < 4)
  1110. dsp_w = 4;
  1111. actual_w = dsp_w * actual_w / drm_rect_width(dest);
  1112. }
  1113. dsp_h = drm_rect_height(dest);
  1114. if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
  1115. drm_err(vop2->drm, "vp%d %s dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
  1116. vp->id, win->data->name, dest->y1, dsp_h, adjusted_mode->vdisplay);
  1117. dsp_h = adjusted_mode->vdisplay - dest->y1;
  1118. if (dsp_h < 4)
  1119. dsp_h = 4;
  1120. actual_h = dsp_h * actual_h / drm_rect_height(dest);
  1121. }
  1122. /*
  1123. * This is workaround solution for IC design:
  1124. * esmart can't support scale down when actual_w % 16 == 1.
  1125. */
  1126. if (!(win->data->feature & WIN_FEATURE_AFBDC)) {
  1127. if (actual_w > dsp_w && (actual_w & 0xf) == 1) {
  1128. drm_err(vop2->drm, "vp%d %s act_w[%d] MODE 16 == 1\n",
  1129. vp->id, win->data->name, actual_w);
  1130. actual_w -= 1;
  1131. }
  1132. }
  1133. if (afbc_en && actual_w % 4) {
  1134. drm_err(vop2->drm, "vp%d %s actual_w[%d] not 4 pixel aligned\n",
  1135. vp->id, win->data->name, actual_w);
  1136. actual_w = ALIGN_DOWN(actual_w, 4);
  1137. }
  1138. act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
  1139. dsp_info = (dsp_h - 1) << 16 | ((dsp_w - 1) & 0xffff);
  1140. format = vop2_convert_format(fb->format->format);
  1141. half_block_en = vop2_half_block_enable(pstate);
  1142. drm_dbg(vop2->drm, "vp%d update %s[%dx%d->%dx%d@%dx%d] fmt[%p4cc_%s] addr[%pad]\n",
  1143. vp->id, win->data->name, actual_w, actual_h, dsp_w, dsp_h,
  1144. dest->x1, dest->y1,
  1145. &fb->format->format,
  1146. afbc_en ? "AFBC" : "", &yrgb_mst);
  1147. if (vop2->data->soc_id > 3568) {
  1148. vop2_win_write(win, VOP2_WIN_AXI_BUS_ID, win->data->axi_bus_id);
  1149. vop2_win_write(win, VOP2_WIN_AXI_YRGB_R_ID, win->data->axi_yrgb_r_id);
  1150. vop2_win_write(win, VOP2_WIN_AXI_UV_R_ID, win->data->axi_uv_r_id);
  1151. }
  1152. if (vop2_cluster_window(win))
  1153. vop2_win_write(win, VOP2_WIN_AFBC_HALF_BLOCK_EN, half_block_en);
  1154. if (afbc_en) {
  1155. u32 stride;
  1156. /* the afbc superblock is 16 x 16 */
  1157. afbc_format = vop2_convert_afbc_format(fb->format->format);
  1158. /* Enable color transform for YTR */
  1159. if (fb->modifier & AFBC_FORMAT_MOD_YTR)
  1160. afbc_format |= (1 << 4);
  1161. afbc_tile_num = ALIGN(actual_w, 16) >> 4;
  1162. /*
  1163. * AFBC pic_vir_width is count by pixel, this is different
  1164. * with WIN_VIR_STRIDE.
  1165. */
  1166. stride = (fb->pitches[0] << 3) / bpp;
  1167. if ((stride & 0x3f) && (xmirror || rotate_90 || rotate_270))
  1168. drm_err(vop2->drm, "vp%d %s stride[%d] not 64 pixel aligned\n",
  1169. vp->id, win->data->name, stride);
  1170. uv_swap = vop2_afbc_uv_swap(fb->format->format);
  1171. /*
  1172. * This is a workaround for crazy IC design, Cluster
  1173. * and Esmart/Smart use different format configuration map:
  1174. * YUV420_10BIT: 0x10 for Cluster, 0x14 for Esmart/Smart.
  1175. *
  1176. * This is one thing we can make the convert simple:
  1177. * AFBCD decode all the YUV data to YUV444. So we just
  1178. * set all the yuv 10 bit to YUV444_10.
  1179. */
  1180. if (fb->format->is_yuv && bpp == 10)
  1181. format = VOP2_CLUSTER_YUV444_10;
  1182. if (vop2_cluster_window(win))
  1183. vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 1);
  1184. vop2_win_write(win, VOP2_WIN_AFBC_FORMAT, afbc_format);
  1185. vop2_win_write(win, VOP2_WIN_AFBC_UV_SWAP, uv_swap);
  1186. /*
  1187. * On rk3566/8, this bit is auto gating enable,
  1188. * but this function is not work well so we need
  1189. * to disable it for these two platform.
  1190. * On rk3588, and the following new soc(rk3528/rk3576),
  1191. * this bit is gating disable, we should write 1 to
  1192. * disable gating when enable afbc.
  1193. */
  1194. if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
  1195. vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 0);
  1196. else
  1197. vop2_win_write(win, VOP2_WIN_AFBC_AUTO_GATING_EN, 1);
  1198. vop2_win_write(win, VOP2_WIN_AFBC_BLOCK_SPLIT_EN, 0);
  1199. transform_offset = vop2_afbc_transform_offset(pstate, half_block_en);
  1200. vop2_win_write(win, VOP2_WIN_AFBC_HDR_PTR, yrgb_mst);
  1201. vop2_win_write(win, VOP2_WIN_AFBC_PIC_SIZE, act_info);
  1202. vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, transform_offset);
  1203. vop2_win_write(win, VOP2_WIN_AFBC_PIC_OFFSET, ((src->x1 >> 16) | src->y1));
  1204. vop2_win_write(win, VOP2_WIN_AFBC_DSP_OFFSET, (dest->x1 | (dest->y1 << 16)));
  1205. vop2_win_write(win, VOP2_WIN_AFBC_PIC_VIR_WIDTH, stride);
  1206. vop2_win_write(win, VOP2_WIN_AFBC_TILE_NUM, afbc_tile_num);
  1207. vop2_win_write(win, VOP2_WIN_XMIRROR, xmirror);
  1208. vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_270, rotate_270);
  1209. vop2_win_write(win, VOP2_WIN_AFBC_ROTATE_90, rotate_90);
  1210. } else {
  1211. if (vop2_cluster_window(win)) {
  1212. vop2_win_write(win, VOP2_WIN_AFBC_ENABLE, 0);
  1213. vop2_win_write(win, VOP2_WIN_AFBC_TRANSFORM_OFFSET, 0);
  1214. }
  1215. vop2_win_write(win, VOP2_WIN_YRGB_VIR, DIV_ROUND_UP(fb->pitches[0], 4));
  1216. }
  1217. vop2_win_write(win, VOP2_WIN_YMIRROR, ymirror);
  1218. if (rotate_90 || rotate_270) {
  1219. act_info = swahw32(act_info);
  1220. actual_w = drm_rect_height(src) >> 16;
  1221. actual_h = drm_rect_width(src) >> 16;
  1222. }
  1223. vop2_win_write(win, VOP2_WIN_FORMAT, format);
  1224. vop2_win_write(win, VOP2_WIN_YRGB_MST, yrgb_mst);
  1225. rb_swap = vop2_win_rb_swap(fb->format->format);
  1226. vop2_win_write(win, VOP2_WIN_RB_SWAP, rb_swap);
  1227. uv_swap = vop2_win_uv_swap(fb->format->format);
  1228. vop2_win_write(win, VOP2_WIN_UV_SWAP, uv_swap);
  1229. if (fb->format->is_yuv) {
  1230. vop2_win_write(win, VOP2_WIN_UV_VIR, DIV_ROUND_UP(fb->pitches[1], 4));
  1231. vop2_win_write(win, VOP2_WIN_UV_MST, uv_mst);
  1232. }
  1233. vop2_setup_scale(vop2, win, actual_w, actual_h, dsp_w, dsp_h, fb->format->format);
  1234. if (!vop2_cluster_window(win))
  1235. vop2_plane_setup_color_key(plane, 0);
  1236. vop2_win_write(win, VOP2_WIN_ACT_INFO, act_info);
  1237. vop2_win_write(win, VOP2_WIN_DSP_INFO, dsp_info);
  1238. vop2_win_write(win, VOP2_WIN_DSP_ST, dest->y1 << 16 | (dest->x1 & 0xffff));
  1239. vop2_setup_csc_mode(vp, win, pstate);
  1240. dither_up = vop2_win_dither_up(fb->format->format);
  1241. vop2_win_write(win, VOP2_WIN_DITHER_UP, dither_up);
  1242. vop2_win_write(win, VOP2_WIN_ENABLE, 1);
  1243. if (vop2_cluster_window(win)) {
  1244. int lb_mode = vop2_get_cluster_lb_mode(win, pstate);
  1245. vop2_win_write(win, VOP2_WIN_CLUSTER_LB_MODE, lb_mode);
  1246. vop2_win_write(win, VOP2_WIN_CLUSTER_ENABLE, 1);
  1247. }
  1248. }
  1249. static const struct drm_plane_helper_funcs vop2_plane_helper_funcs = {
  1250. .atomic_check = vop2_plane_atomic_check,
  1251. .atomic_update = vop2_plane_atomic_update,
  1252. .atomic_disable = vop2_plane_atomic_disable,
  1253. };
  1254. static const struct drm_plane_funcs vop2_plane_funcs = {
  1255. .update_plane = drm_atomic_helper_update_plane,
  1256. .disable_plane = drm_atomic_helper_disable_plane,
  1257. .destroy = drm_plane_cleanup,
  1258. .reset = drm_atomic_helper_plane_reset,
  1259. .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
  1260. .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
  1261. .format_mod_supported = rockchip_vop2_mod_supported,
  1262. };
  1263. static int vop2_crtc_enable_vblank(struct drm_crtc *crtc)
  1264. {
  1265. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1266. vop2_crtc_enable_irq(vp, VP_INT_FS_FIELD);
  1267. return 0;
  1268. }
  1269. static void vop2_crtc_disable_vblank(struct drm_crtc *crtc)
  1270. {
  1271. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1272. vop2_crtc_disable_irq(vp, VP_INT_FS_FIELD);
  1273. }
  1274. static bool vop2_crtc_mode_fixup(struct drm_crtc *crtc,
  1275. const struct drm_display_mode *mode,
  1276. struct drm_display_mode *adj_mode)
  1277. {
  1278. drm_mode_set_crtcinfo(adj_mode, CRTC_INTERLACE_HALVE_V |
  1279. CRTC_STEREO_DOUBLE);
  1280. return true;
  1281. }
  1282. static void vop2_dither_setup(struct drm_crtc *crtc, u32 *dsp_ctrl)
  1283. {
  1284. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
  1285. switch (vcstate->bus_format) {
  1286. case MEDIA_BUS_FMT_RGB565_1X16:
  1287. *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
  1288. break;
  1289. case MEDIA_BUS_FMT_RGB666_1X18:
  1290. case MEDIA_BUS_FMT_RGB666_1X24_CPADHI:
  1291. case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
  1292. *dsp_ctrl |= RK3568_VP_DSP_CTRL__DITHER_DOWN_EN;
  1293. *dsp_ctrl |= RGB888_TO_RGB666;
  1294. break;
  1295. case MEDIA_BUS_FMT_YUV8_1X24:
  1296. case MEDIA_BUS_FMT_UYYVYY8_0_5X24:
  1297. *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
  1298. break;
  1299. default:
  1300. break;
  1301. }
  1302. if (vcstate->output_mode != ROCKCHIP_OUT_MODE_AAAA)
  1303. *dsp_ctrl |= RK3568_VP_DSP_CTRL__PRE_DITHER_DOWN_EN;
  1304. *dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__DITHER_DOWN_SEL,
  1305. DITHER_DOWN_ALLEGRO);
  1306. }
  1307. static void vop2_post_config(struct drm_crtc *crtc)
  1308. {
  1309. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1310. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  1311. u16 vtotal = mode->crtc_vtotal;
  1312. u16 hdisplay = mode->crtc_hdisplay;
  1313. u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
  1314. u16 vdisplay = mode->crtc_vdisplay;
  1315. u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
  1316. u32 left_margin = 100, right_margin = 100;
  1317. u32 top_margin = 100, bottom_margin = 100;
  1318. u16 hsize = hdisplay * (left_margin + right_margin) / 200;
  1319. u16 vsize = vdisplay * (top_margin + bottom_margin) / 200;
  1320. u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
  1321. u16 hact_end, vact_end;
  1322. u32 val;
  1323. u32 bg_dly;
  1324. u32 pre_scan_dly;
  1325. bg_dly = vp->data->pre_scan_max_dly[3];
  1326. vop2_writel(vp->vop2, RK3568_VP_BG_MIX_CTRL(vp->id),
  1327. FIELD_PREP(RK3568_VP_BG_MIX_CTRL__BG_DLY, bg_dly));
  1328. pre_scan_dly = ((bg_dly + (hdisplay >> 1) - 1) << 16) | hsync_len;
  1329. vop2_vp_write(vp, RK3568_VP_PRE_SCAN_HTIMING, pre_scan_dly);
  1330. vsize = rounddown(vsize, 2);
  1331. hsize = rounddown(hsize, 2);
  1332. hact_st += hdisplay * (100 - left_margin) / 200;
  1333. hact_end = hact_st + hsize;
  1334. val = hact_st << 16;
  1335. val |= hact_end;
  1336. vop2_vp_write(vp, RK3568_VP_POST_DSP_HACT_INFO, val);
  1337. vact_st += vdisplay * (100 - top_margin) / 200;
  1338. vact_end = vact_st + vsize;
  1339. val = vact_st << 16;
  1340. val |= vact_end;
  1341. vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO, val);
  1342. val = scl_cal_scale2(vdisplay, vsize) << 16;
  1343. val |= scl_cal_scale2(hdisplay, hsize);
  1344. vop2_vp_write(vp, RK3568_VP_POST_SCL_FACTOR_YRGB, val);
  1345. val = 0;
  1346. if (hdisplay != hsize)
  1347. val |= RK3568_VP_POST_SCL_CTRL__HSCALEDOWN;
  1348. if (vdisplay != vsize)
  1349. val |= RK3568_VP_POST_SCL_CTRL__VSCALEDOWN;
  1350. vop2_vp_write(vp, RK3568_VP_POST_SCL_CTRL, val);
  1351. if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  1352. u16 vact_st_f1 = vtotal + vact_st + 1;
  1353. u16 vact_end_f1 = vact_st_f1 + vsize;
  1354. val = vact_st_f1 << 16 | vact_end_f1;
  1355. vop2_vp_write(vp, RK3568_VP_POST_DSP_VACT_INFO_F1, val);
  1356. }
  1357. vop2_vp_write(vp, RK3568_VP_DSP_BG, 0);
  1358. }
  1359. static unsigned long rk3568_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
  1360. {
  1361. struct vop2 *vop2 = vp->vop2;
  1362. struct drm_crtc *crtc = &vp->crtc;
  1363. u32 die, dip;
  1364. die = vop2_readl(vop2, RK3568_DSP_IF_EN);
  1365. dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
  1366. switch (id) {
  1367. case ROCKCHIP_VOP2_EP_RGB0:
  1368. die &= ~RK3568_SYS_DSP_INFACE_EN_RGB_MUX;
  1369. die |= RK3568_SYS_DSP_INFACE_EN_RGB |
  1370. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_RGB_MUX, vp->id);
  1371. dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
  1372. dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
  1373. if (polflags & POLFLAG_DCLK_INV)
  1374. regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16) | BIT(3));
  1375. else
  1376. regmap_write(vop2->sys_grf, RK3568_GRF_VO_CON1, BIT(3 + 16));
  1377. break;
  1378. case ROCKCHIP_VOP2_EP_HDMI0:
  1379. die &= ~RK3568_SYS_DSP_INFACE_EN_HDMI_MUX;
  1380. die |= RK3568_SYS_DSP_INFACE_EN_HDMI |
  1381. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_HDMI_MUX, vp->id);
  1382. dip &= ~RK3568_DSP_IF_POL__HDMI_PIN_POL;
  1383. dip |= FIELD_PREP(RK3568_DSP_IF_POL__HDMI_PIN_POL, polflags);
  1384. break;
  1385. case ROCKCHIP_VOP2_EP_EDP0:
  1386. die &= ~RK3568_SYS_DSP_INFACE_EN_EDP_MUX;
  1387. die |= RK3568_SYS_DSP_INFACE_EN_EDP |
  1388. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_EDP_MUX, vp->id);
  1389. dip &= ~RK3568_DSP_IF_POL__EDP_PIN_POL;
  1390. dip |= FIELD_PREP(RK3568_DSP_IF_POL__EDP_PIN_POL, polflags);
  1391. break;
  1392. case ROCKCHIP_VOP2_EP_MIPI0:
  1393. die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX;
  1394. die |= RK3568_SYS_DSP_INFACE_EN_MIPI0 |
  1395. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI0_MUX, vp->id);
  1396. dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
  1397. dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
  1398. break;
  1399. case ROCKCHIP_VOP2_EP_MIPI1:
  1400. die &= ~RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX;
  1401. die |= RK3568_SYS_DSP_INFACE_EN_MIPI1 |
  1402. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
  1403. dip &= ~RK3568_DSP_IF_POL__MIPI_PIN_POL;
  1404. dip |= FIELD_PREP(RK3568_DSP_IF_POL__MIPI_PIN_POL, polflags);
  1405. break;
  1406. case ROCKCHIP_VOP2_EP_LVDS0:
  1407. die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX;
  1408. die |= RK3568_SYS_DSP_INFACE_EN_LVDS0 |
  1409. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS0_MUX, vp->id);
  1410. dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
  1411. dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
  1412. break;
  1413. case ROCKCHIP_VOP2_EP_LVDS1:
  1414. die &= ~RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX;
  1415. die |= RK3568_SYS_DSP_INFACE_EN_LVDS1 |
  1416. FIELD_PREP(RK3568_SYS_DSP_INFACE_EN_LVDS1_MUX, vp->id);
  1417. dip &= ~RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL;
  1418. dip |= FIELD_PREP(RK3568_DSP_IF_POL__RGB_LVDS_PIN_POL, polflags);
  1419. break;
  1420. default:
  1421. drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
  1422. return 0;
  1423. }
  1424. dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
  1425. vop2_writel(vop2, RK3568_DSP_IF_EN, die);
  1426. vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
  1427. return crtc->state->adjusted_mode.crtc_clock * 1000LL;
  1428. }
  1429. /*
  1430. * calc the dclk on rk3588
  1431. * the available div of dclk is 1, 2, 4
  1432. */
  1433. static unsigned long rk3588_calc_dclk(unsigned long child_clk, unsigned long max_dclk)
  1434. {
  1435. if (child_clk * 4 <= max_dclk)
  1436. return child_clk * 4;
  1437. else if (child_clk * 2 <= max_dclk)
  1438. return child_clk * 2;
  1439. else if (child_clk <= max_dclk)
  1440. return child_clk;
  1441. else
  1442. return 0;
  1443. }
  1444. /*
  1445. * 4 pixclk/cycle on rk3588
  1446. * RGB/eDP/HDMI: if_pixclk >= dclk_core
  1447. * DP: dp_pixclk = dclk_out <= dclk_core
  1448. * DSI: mipi_pixclk <= dclk_out <= dclk_core
  1449. */
  1450. static unsigned long rk3588_calc_cru_cfg(struct vop2_video_port *vp, int id,
  1451. int *dclk_core_div, int *dclk_out_div,
  1452. int *if_pixclk_div, int *if_dclk_div)
  1453. {
  1454. struct vop2 *vop2 = vp->vop2;
  1455. struct drm_crtc *crtc = &vp->crtc;
  1456. struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
  1457. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
  1458. int output_mode = vcstate->output_mode;
  1459. unsigned long v_pixclk = adjusted_mode->crtc_clock * 1000LL; /* video timing pixclk */
  1460. unsigned long dclk_core_rate = v_pixclk >> 2;
  1461. unsigned long dclk_rate = v_pixclk;
  1462. unsigned long dclk_out_rate;
  1463. unsigned long if_pixclk_rate;
  1464. int K = 1;
  1465. if (vop2_output_if_is_hdmi(id)) {
  1466. /*
  1467. * K = 2: dclk_core = if_pixclk_rate > if_dclk_rate
  1468. * K = 1: dclk_core = hdmie_edp_dclk > if_pixclk_rate
  1469. */
  1470. if (output_mode == ROCKCHIP_OUT_MODE_YUV420) {
  1471. dclk_rate = dclk_rate >> 1;
  1472. K = 2;
  1473. }
  1474. if_pixclk_rate = (dclk_core_rate << 1) / K;
  1475. /*
  1476. * if_dclk_rate = dclk_core_rate / K;
  1477. * *if_pixclk_div = dclk_rate / if_pixclk_rate;
  1478. * *if_dclk_div = dclk_rate / if_dclk_rate;
  1479. */
  1480. *if_pixclk_div = 2;
  1481. *if_dclk_div = 4;
  1482. } else if (vop2_output_if_is_edp(id)) {
  1483. /*
  1484. * edp_pixclk = edp_dclk > dclk_core
  1485. */
  1486. if_pixclk_rate = v_pixclk / K;
  1487. dclk_rate = if_pixclk_rate * K;
  1488. /*
  1489. * *if_pixclk_div = dclk_rate / if_pixclk_rate;
  1490. * *if_dclk_div = *if_pixclk_div;
  1491. */
  1492. *if_pixclk_div = K;
  1493. *if_dclk_div = K;
  1494. } else if (vop2_output_if_is_dp(id)) {
  1495. if (output_mode == ROCKCHIP_OUT_MODE_YUV420)
  1496. dclk_out_rate = v_pixclk >> 3;
  1497. else
  1498. dclk_out_rate = v_pixclk >> 2;
  1499. dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
  1500. if (!dclk_rate) {
  1501. drm_err(vop2->drm, "DP dclk_out_rate out of range, dclk_out_rate: %ld Hz\n",
  1502. dclk_out_rate);
  1503. return 0;
  1504. }
  1505. *dclk_out_div = dclk_rate / dclk_out_rate;
  1506. } else if (vop2_output_if_is_mipi(id)) {
  1507. if_pixclk_rate = dclk_core_rate / K;
  1508. /*
  1509. * dclk_core = dclk_out * K = if_pixclk * K = v_pixclk / 4
  1510. */
  1511. dclk_out_rate = if_pixclk_rate;
  1512. /*
  1513. * dclk_rate = N * dclk_core_rate N = (1,2,4 ),
  1514. * we get a little factor here
  1515. */
  1516. dclk_rate = rk3588_calc_dclk(dclk_out_rate, 600000000);
  1517. if (!dclk_rate) {
  1518. drm_err(vop2->drm, "MIPI dclk out of range, dclk_out_rate: %ld Hz\n",
  1519. dclk_out_rate);
  1520. return 0;
  1521. }
  1522. *dclk_out_div = dclk_rate / dclk_out_rate;
  1523. /*
  1524. * mipi pixclk == dclk_out
  1525. */
  1526. *if_pixclk_div = 1;
  1527. } else if (vop2_output_if_is_dpi(id)) {
  1528. dclk_rate = v_pixclk;
  1529. }
  1530. *dclk_core_div = dclk_rate / dclk_core_rate;
  1531. *if_pixclk_div = ilog2(*if_pixclk_div);
  1532. *if_dclk_div = ilog2(*if_dclk_div);
  1533. *dclk_core_div = ilog2(*dclk_core_div);
  1534. *dclk_out_div = ilog2(*dclk_out_div);
  1535. drm_dbg(vop2->drm, "dclk: %ld, pixclk_div: %d, dclk_div: %d\n",
  1536. dclk_rate, *if_pixclk_div, *if_dclk_div);
  1537. return dclk_rate;
  1538. }
  1539. /*
  1540. * MIPI port mux on rk3588:
  1541. * 0: Video Port2
  1542. * 1: Video Port3
  1543. * 3: Video Port 1(MIPI1 only)
  1544. */
  1545. static u32 rk3588_get_mipi_port_mux(int vp_id)
  1546. {
  1547. if (vp_id == 1)
  1548. return 3;
  1549. else if (vp_id == 3)
  1550. return 1;
  1551. else
  1552. return 0;
  1553. }
  1554. static u32 rk3588_get_hdmi_pol(u32 flags)
  1555. {
  1556. u32 val;
  1557. val = (flags & DRM_MODE_FLAG_NHSYNC) ? BIT(HSYNC_POSITIVE) : 0;
  1558. val |= (flags & DRM_MODE_FLAG_NVSYNC) ? BIT(VSYNC_POSITIVE) : 0;
  1559. return val;
  1560. }
  1561. static unsigned long rk3588_set_intf_mux(struct vop2_video_port *vp, int id, u32 polflags)
  1562. {
  1563. struct vop2 *vop2 = vp->vop2;
  1564. int dclk_core_div, dclk_out_div, if_pixclk_div, if_dclk_div;
  1565. unsigned long clock;
  1566. u32 die, dip, div, vp_clk_div, val;
  1567. clock = rk3588_calc_cru_cfg(vp, id, &dclk_core_div, &dclk_out_div,
  1568. &if_pixclk_div, &if_dclk_div);
  1569. if (!clock)
  1570. return 0;
  1571. vp_clk_div = FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_CORE_DIV, dclk_core_div);
  1572. vp_clk_div |= FIELD_PREP(RK3588_VP_CLK_CTRL__DCLK_OUT_DIV, dclk_out_div);
  1573. die = vop2_readl(vop2, RK3568_DSP_IF_EN);
  1574. dip = vop2_readl(vop2, RK3568_DSP_IF_POL);
  1575. div = vop2_readl(vop2, RK3568_DSP_IF_CTRL);
  1576. switch (id) {
  1577. case ROCKCHIP_VOP2_EP_HDMI0:
  1578. div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
  1579. div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
  1580. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
  1581. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
  1582. die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
  1583. die |= RK3588_SYS_DSP_INFACE_EN_HDMI0 |
  1584. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
  1585. val = rk3588_get_hdmi_pol(polflags);
  1586. regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 1, 1));
  1587. regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 6, 5));
  1588. break;
  1589. case ROCKCHIP_VOP2_EP_HDMI1:
  1590. div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
  1591. div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
  1592. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV, if_dclk_div);
  1593. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV, if_pixclk_div);
  1594. die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
  1595. die |= RK3588_SYS_DSP_INFACE_EN_HDMI1 |
  1596. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
  1597. val = rk3588_get_hdmi_pol(polflags);
  1598. regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 4, 4));
  1599. regmap_write(vop2->vo1_grf, RK3588_GRF_VO1_CON0, HIWORD_UPDATE(val, 8, 7));
  1600. break;
  1601. case ROCKCHIP_VOP2_EP_EDP0:
  1602. div &= ~RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV;
  1603. div &= ~RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV;
  1604. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
  1605. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
  1606. die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX;
  1607. die |= RK3588_SYS_DSP_INFACE_EN_EDP0 |
  1608. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI0_MUX, vp->id);
  1609. regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 0, 0));
  1610. break;
  1611. case ROCKCHIP_VOP2_EP_EDP1:
  1612. div &= ~RK3588_DSP_IF_EDP_HDMI1_DCLK_DIV;
  1613. div &= ~RK3588_DSP_IF_EDP_HDMI1_PCLK_DIV;
  1614. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_DCLK_DIV, if_dclk_div);
  1615. div |= FIELD_PREP(RK3588_DSP_IF_EDP_HDMI0_PCLK_DIV, if_pixclk_div);
  1616. die &= ~RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX;
  1617. die |= RK3588_SYS_DSP_INFACE_EN_EDP1 |
  1618. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_EDP_HDMI1_MUX, vp->id);
  1619. regmap_write(vop2->vop_grf, RK3588_GRF_VOP_CON2, HIWORD_UPDATE(1, 3, 3));
  1620. break;
  1621. case ROCKCHIP_VOP2_EP_MIPI0:
  1622. div &= ~RK3588_DSP_IF_MIPI0_PCLK_DIV;
  1623. div |= FIELD_PREP(RK3588_DSP_IF_MIPI0_PCLK_DIV, if_pixclk_div);
  1624. die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX;
  1625. val = rk3588_get_mipi_port_mux(vp->id);
  1626. die |= RK3588_SYS_DSP_INFACE_EN_MIPI0 |
  1627. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI0_MUX, !!val);
  1628. break;
  1629. case ROCKCHIP_VOP2_EP_MIPI1:
  1630. div &= ~RK3588_DSP_IF_MIPI1_PCLK_DIV;
  1631. div |= FIELD_PREP(RK3588_DSP_IF_MIPI1_PCLK_DIV, if_pixclk_div);
  1632. die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
  1633. val = rk3588_get_mipi_port_mux(vp->id);
  1634. die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
  1635. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, val);
  1636. break;
  1637. case ROCKCHIP_VOP2_EP_DP0:
  1638. die &= ~RK3588_SYS_DSP_INFACE_EN_DP0_MUX;
  1639. die |= RK3588_SYS_DSP_INFACE_EN_DP0 |
  1640. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_DP0_MUX, vp->id);
  1641. dip &= ~RK3588_DSP_IF_POL__DP0_PIN_POL;
  1642. dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP0_PIN_POL, polflags);
  1643. break;
  1644. case ROCKCHIP_VOP2_EP_DP1:
  1645. die &= ~RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX;
  1646. die |= RK3588_SYS_DSP_INFACE_EN_MIPI1 |
  1647. FIELD_PREP(RK3588_SYS_DSP_INFACE_EN_MIPI1_MUX, vp->id);
  1648. dip &= ~RK3588_DSP_IF_POL__DP1_PIN_POL;
  1649. dip |= FIELD_PREP(RK3588_DSP_IF_POL__DP1_PIN_POL, polflags);
  1650. break;
  1651. default:
  1652. drm_err(vop2->drm, "Invalid interface id %d on vp%d\n", id, vp->id);
  1653. return 0;
  1654. }
  1655. dip |= RK3568_DSP_IF_POL__CFG_DONE_IMD;
  1656. vop2_vp_write(vp, RK3588_VP_CLK_CTRL, vp_clk_div);
  1657. vop2_writel(vop2, RK3568_DSP_IF_EN, die);
  1658. vop2_writel(vop2, RK3568_DSP_IF_CTRL, div);
  1659. vop2_writel(vop2, RK3568_DSP_IF_POL, dip);
  1660. return clock;
  1661. }
  1662. static unsigned long vop2_set_intf_mux(struct vop2_video_port *vp, int ep_id, u32 polflags)
  1663. {
  1664. struct vop2 *vop2 = vp->vop2;
  1665. if (vop2->data->soc_id == 3566 || vop2->data->soc_id == 3568)
  1666. return rk3568_set_intf_mux(vp, ep_id, polflags);
  1667. else if (vop2->data->soc_id == 3588)
  1668. return rk3588_set_intf_mux(vp, ep_id, polflags);
  1669. else
  1670. return 0;
  1671. }
  1672. static int us_to_vertical_line(struct drm_display_mode *mode, int us)
  1673. {
  1674. return us * mode->clock / mode->htotal / 1000;
  1675. }
  1676. static void vop2_crtc_atomic_enable(struct drm_crtc *crtc,
  1677. struct drm_atomic_state *state)
  1678. {
  1679. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1680. struct vop2 *vop2 = vp->vop2;
  1681. const struct vop2_data *vop2_data = vop2->data;
  1682. const struct vop2_video_port_data *vp_data = &vop2_data->vp[vp->id];
  1683. struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
  1684. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(crtc->state);
  1685. struct drm_display_mode *mode = &crtc->state->adjusted_mode;
  1686. unsigned long clock = mode->crtc_clock * 1000;
  1687. u16 hsync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
  1688. u16 hdisplay = mode->crtc_hdisplay;
  1689. u16 htotal = mode->crtc_htotal;
  1690. u16 hact_st = mode->crtc_htotal - mode->crtc_hsync_start;
  1691. u16 hact_end = hact_st + hdisplay;
  1692. u16 vdisplay = mode->crtc_vdisplay;
  1693. u16 vtotal = mode->crtc_vtotal;
  1694. u16 vsync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
  1695. u16 vact_st = mode->crtc_vtotal - mode->crtc_vsync_start;
  1696. u16 vact_end = vact_st + vdisplay;
  1697. u8 out_mode;
  1698. u32 dsp_ctrl = 0;
  1699. int act_end;
  1700. u32 val, polflags;
  1701. int ret;
  1702. struct drm_encoder *encoder;
  1703. drm_dbg(vop2->drm, "Update mode to %dx%d%s%d, type: %d for vp%d\n",
  1704. hdisplay, vdisplay, mode->flags & DRM_MODE_FLAG_INTERLACE ? "i" : "p",
  1705. drm_mode_vrefresh(mode), vcstate->output_type, vp->id);
  1706. vop2_lock(vop2);
  1707. ret = clk_prepare_enable(vp->dclk);
  1708. if (ret < 0) {
  1709. drm_err(vop2->drm, "failed to enable dclk for video port%d - %d\n",
  1710. vp->id, ret);
  1711. vop2_unlock(vop2);
  1712. return;
  1713. }
  1714. if (!vop2->enable_count)
  1715. vop2_enable(vop2);
  1716. vop2->enable_count++;
  1717. vcstate->yuv_overlay = is_yuv_output(vcstate->bus_format);
  1718. vop2_crtc_enable_irq(vp, VP_INT_POST_BUF_EMPTY);
  1719. polflags = 0;
  1720. if (vcstate->bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
  1721. polflags |= POLFLAG_DCLK_INV;
  1722. if (mode->flags & DRM_MODE_FLAG_PHSYNC)
  1723. polflags |= BIT(HSYNC_POSITIVE);
  1724. if (mode->flags & DRM_MODE_FLAG_PVSYNC)
  1725. polflags |= BIT(VSYNC_POSITIVE);
  1726. drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
  1727. struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
  1728. /*
  1729. * for drive a high resolution(4KP120, 8K), vop on rk3588/rk3576 need
  1730. * process multi(1/2/4/8) pixels per cycle, so the dclk feed by the
  1731. * system cru may be the 1/2 or 1/4 of mode->clock.
  1732. */
  1733. clock = vop2_set_intf_mux(vp, rkencoder->crtc_endpoint_id, polflags);
  1734. }
  1735. if (!clock) {
  1736. vop2_unlock(vop2);
  1737. return;
  1738. }
  1739. if (vcstate->output_mode == ROCKCHIP_OUT_MODE_AAAA &&
  1740. !(vp_data->feature & VOP2_VP_FEATURE_OUTPUT_10BIT))
  1741. out_mode = ROCKCHIP_OUT_MODE_P888;
  1742. else
  1743. out_mode = vcstate->output_mode;
  1744. dsp_ctrl |= FIELD_PREP(RK3568_VP_DSP_CTRL__OUT_MODE, out_mode);
  1745. if (vop2_output_uv_swap(vcstate->bus_format, vcstate->output_mode))
  1746. dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RB_SWAP;
  1747. if (vop2_output_rg_swap(vop2, vcstate->bus_format))
  1748. dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_RG_SWAP;
  1749. if (vcstate->yuv_overlay)
  1750. dsp_ctrl |= RK3568_VP_DSP_CTRL__POST_DSP_OUT_R2Y;
  1751. vop2_dither_setup(crtc, &dsp_ctrl);
  1752. vop2_vp_write(vp, RK3568_VP_DSP_HTOTAL_HS_END, (htotal << 16) | hsync_len);
  1753. val = hact_st << 16;
  1754. val |= hact_end;
  1755. vop2_vp_write(vp, RK3568_VP_DSP_HACT_ST_END, val);
  1756. val = vact_st << 16;
  1757. val |= vact_end;
  1758. vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END, val);
  1759. if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  1760. u16 vact_st_f1 = vtotal + vact_st + 1;
  1761. u16 vact_end_f1 = vact_st_f1 + vdisplay;
  1762. val = vact_st_f1 << 16 | vact_end_f1;
  1763. vop2_vp_write(vp, RK3568_VP_DSP_VACT_ST_END_F1, val);
  1764. val = vtotal << 16 | (vtotal + vsync_len);
  1765. vop2_vp_write(vp, RK3568_VP_DSP_VS_ST_END_F1, val);
  1766. dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_INTERLACE;
  1767. dsp_ctrl |= RK3568_VP_DSP_CTRL__DSP_FILED_POL;
  1768. dsp_ctrl |= RK3568_VP_DSP_CTRL__P2I_EN;
  1769. vtotal += vtotal + 1;
  1770. act_end = vact_end_f1;
  1771. } else {
  1772. act_end = vact_end;
  1773. }
  1774. vop2_writel(vop2, RK3568_VP_LINE_FLAG(vp->id),
  1775. (act_end - us_to_vertical_line(mode, 0)) << 16 | act_end);
  1776. vop2_vp_write(vp, RK3568_VP_DSP_VTOTAL_VS_END, vtotal << 16 | vsync_len);
  1777. if (mode->flags & DRM_MODE_FLAG_DBLCLK) {
  1778. dsp_ctrl |= RK3568_VP_DSP_CTRL__CORE_DCLK_DIV;
  1779. clock *= 2;
  1780. }
  1781. vop2_vp_write(vp, RK3568_VP_MIPI_CTRL, 0);
  1782. /*
  1783. * Switch to HDMI PHY PLL as DCLK source for display modes up
  1784. * to 4K@60Hz, if available, otherwise keep using the system CRU.
  1785. */
  1786. if (vop2->pll_hdmiphy0 && clock <= VOP2_MAX_DCLK_RATE) {
  1787. drm_for_each_encoder_mask(encoder, crtc->dev, crtc_state->encoder_mask) {
  1788. struct rockchip_encoder *rkencoder = to_rockchip_encoder(encoder);
  1789. if (rkencoder->crtc_endpoint_id == ROCKCHIP_VOP2_EP_HDMI0) {
  1790. if (!vp->dclk_src)
  1791. vp->dclk_src = clk_get_parent(vp->dclk);
  1792. ret = clk_set_parent(vp->dclk, vop2->pll_hdmiphy0);
  1793. if (ret < 0)
  1794. drm_warn(vop2->drm,
  1795. "Could not switch to HDMI0 PHY PLL: %d\n", ret);
  1796. break;
  1797. }
  1798. }
  1799. }
  1800. clk_set_rate(vp->dclk, clock);
  1801. vop2_post_config(crtc);
  1802. vop2_cfg_done(vp);
  1803. vop2_vp_write(vp, RK3568_VP_DSP_CTRL, dsp_ctrl);
  1804. drm_crtc_vblank_on(crtc);
  1805. vop2_unlock(vop2);
  1806. }
  1807. static int vop2_crtc_atomic_check(struct drm_crtc *crtc,
  1808. struct drm_atomic_state *state)
  1809. {
  1810. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  1811. struct drm_plane *plane;
  1812. int nplanes = 0;
  1813. struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
  1814. drm_atomic_crtc_state_for_each_plane(plane, crtc_state)
  1815. nplanes++;
  1816. if (nplanes > vp->nlayers)
  1817. return -EINVAL;
  1818. return 0;
  1819. }
  1820. static bool is_opaque(u16 alpha)
  1821. {
  1822. return (alpha >> 8) == 0xff;
  1823. }
  1824. static void vop2_parse_alpha(struct vop2_alpha_config *alpha_config,
  1825. struct vop2_alpha *alpha)
  1826. {
  1827. int src_glb_alpha_en = is_opaque(alpha_config->src_glb_alpha_value) ? 0 : 1;
  1828. int dst_glb_alpha_en = is_opaque(alpha_config->dst_glb_alpha_value) ? 0 : 1;
  1829. int src_color_mode = alpha_config->src_premulti_en ?
  1830. ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
  1831. int dst_color_mode = alpha_config->dst_premulti_en ?
  1832. ALPHA_SRC_PRE_MUL : ALPHA_SRC_NO_PRE_MUL;
  1833. alpha->src_color_ctrl.val = 0;
  1834. alpha->dst_color_ctrl.val = 0;
  1835. alpha->src_alpha_ctrl.val = 0;
  1836. alpha->dst_alpha_ctrl.val = 0;
  1837. if (!alpha_config->src_pixel_alpha_en)
  1838. alpha->src_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
  1839. else if (alpha_config->src_pixel_alpha_en && !src_glb_alpha_en)
  1840. alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX;
  1841. else
  1842. alpha->src_color_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
  1843. alpha->src_color_ctrl.bits.alpha_en = 1;
  1844. if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_GLOBAL) {
  1845. alpha->src_color_ctrl.bits.color_mode = src_color_mode;
  1846. alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
  1847. } else if (alpha->src_color_ctrl.bits.blend_mode == ALPHA_PER_PIX) {
  1848. alpha->src_color_ctrl.bits.color_mode = src_color_mode;
  1849. alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_ONE;
  1850. } else {
  1851. alpha->src_color_ctrl.bits.color_mode = ALPHA_SRC_PRE_MUL;
  1852. alpha->src_color_ctrl.bits.factor_mode = SRC_FAC_ALPHA_SRC_GLOBAL;
  1853. }
  1854. alpha->src_color_ctrl.bits.glb_alpha = alpha_config->src_glb_alpha_value >> 8;
  1855. alpha->src_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
  1856. alpha->src_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
  1857. alpha->dst_color_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
  1858. alpha->dst_color_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
  1859. alpha->dst_color_ctrl.bits.blend_mode = ALPHA_GLOBAL;
  1860. alpha->dst_color_ctrl.bits.glb_alpha = alpha_config->dst_glb_alpha_value >> 8;
  1861. alpha->dst_color_ctrl.bits.color_mode = dst_color_mode;
  1862. alpha->dst_color_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
  1863. alpha->src_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
  1864. alpha->src_alpha_ctrl.bits.blend_mode = alpha->src_color_ctrl.bits.blend_mode;
  1865. alpha->src_alpha_ctrl.bits.alpha_cal_mode = ALPHA_SATURATION;
  1866. alpha->src_alpha_ctrl.bits.factor_mode = ALPHA_ONE;
  1867. alpha->dst_alpha_ctrl.bits.alpha_mode = ALPHA_STRAIGHT;
  1868. if (alpha_config->dst_pixel_alpha_en && !dst_glb_alpha_en)
  1869. alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX;
  1870. else
  1871. alpha->dst_alpha_ctrl.bits.blend_mode = ALPHA_PER_PIX_GLOBAL;
  1872. alpha->dst_alpha_ctrl.bits.alpha_cal_mode = ALPHA_NO_SATURATION;
  1873. alpha->dst_alpha_ctrl.bits.factor_mode = ALPHA_SRC_INVERSE;
  1874. }
  1875. static int vop2_find_start_mixer_id_for_vp(struct vop2 *vop2, u8 port_id)
  1876. {
  1877. struct vop2_video_port *vp;
  1878. int used_layer = 0;
  1879. int i;
  1880. for (i = 0; i < port_id; i++) {
  1881. vp = &vop2->vps[i];
  1882. used_layer += hweight32(vp->win_mask);
  1883. }
  1884. return used_layer;
  1885. }
  1886. static void vop2_setup_cluster_alpha(struct vop2 *vop2, struct vop2_win *main_win)
  1887. {
  1888. struct vop2_alpha_config alpha_config;
  1889. struct vop2_alpha alpha;
  1890. struct drm_plane_state *bottom_win_pstate;
  1891. bool src_pixel_alpha_en = false;
  1892. u16 src_glb_alpha_val, dst_glb_alpha_val;
  1893. bool premulti_en = false;
  1894. bool swap = false;
  1895. u32 offset = 0;
  1896. /* At one win mode, win0 is dst/bottom win, and win1 is a all zero src/top win */
  1897. bottom_win_pstate = main_win->base.state;
  1898. src_glb_alpha_val = 0;
  1899. dst_glb_alpha_val = main_win->base.state->alpha;
  1900. if (!bottom_win_pstate->fb)
  1901. return;
  1902. alpha_config.src_premulti_en = premulti_en;
  1903. alpha_config.dst_premulti_en = false;
  1904. alpha_config.src_pixel_alpha_en = src_pixel_alpha_en;
  1905. alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
  1906. alpha_config.src_glb_alpha_value = src_glb_alpha_val;
  1907. alpha_config.dst_glb_alpha_value = dst_glb_alpha_val;
  1908. vop2_parse_alpha(&alpha_config, &alpha);
  1909. alpha.src_color_ctrl.bits.src_dst_swap = swap;
  1910. switch (main_win->data->phys_id) {
  1911. case ROCKCHIP_VOP2_CLUSTER0:
  1912. offset = 0x0;
  1913. break;
  1914. case ROCKCHIP_VOP2_CLUSTER1:
  1915. offset = 0x10;
  1916. break;
  1917. case ROCKCHIP_VOP2_CLUSTER2:
  1918. offset = 0x20;
  1919. break;
  1920. case ROCKCHIP_VOP2_CLUSTER3:
  1921. offset = 0x30;
  1922. break;
  1923. }
  1924. vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_COLOR_CTRL + offset,
  1925. alpha.src_color_ctrl.val);
  1926. vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_COLOR_CTRL + offset,
  1927. alpha.dst_color_ctrl.val);
  1928. vop2_writel(vop2, RK3568_CLUSTER0_MIX_SRC_ALPHA_CTRL + offset,
  1929. alpha.src_alpha_ctrl.val);
  1930. vop2_writel(vop2, RK3568_CLUSTER0_MIX_DST_ALPHA_CTRL + offset,
  1931. alpha.dst_alpha_ctrl.val);
  1932. }
  1933. static void vop2_setup_alpha(struct vop2_video_port *vp)
  1934. {
  1935. struct vop2 *vop2 = vp->vop2;
  1936. struct drm_framebuffer *fb;
  1937. struct vop2_alpha_config alpha_config;
  1938. struct vop2_alpha alpha;
  1939. struct drm_plane *plane;
  1940. int pixel_alpha_en;
  1941. int premulti_en, gpremulti_en = 0;
  1942. int mixer_id;
  1943. u32 offset;
  1944. bool bottom_layer_alpha_en = false;
  1945. u32 dst_global_alpha = DRM_BLEND_ALPHA_OPAQUE;
  1946. mixer_id = vop2_find_start_mixer_id_for_vp(vop2, vp->id);
  1947. alpha_config.dst_pixel_alpha_en = true; /* alpha value need transfer to next mix */
  1948. drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
  1949. struct vop2_win *win = to_vop2_win(plane);
  1950. if (plane->state->normalized_zpos == 0 &&
  1951. !is_opaque(plane->state->alpha) &&
  1952. !vop2_cluster_window(win)) {
  1953. /*
  1954. * If bottom layer have global alpha effect [except cluster layer,
  1955. * because cluster have deal with bottom layer global alpha value
  1956. * at cluster mix], bottom layer mix need deal with global alpha.
  1957. */
  1958. bottom_layer_alpha_en = true;
  1959. dst_global_alpha = plane->state->alpha;
  1960. }
  1961. }
  1962. drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
  1963. struct vop2_win *win = to_vop2_win(plane);
  1964. int zpos = plane->state->normalized_zpos;
  1965. /*
  1966. * Need to configure alpha from second layer.
  1967. */
  1968. if (zpos == 0)
  1969. continue;
  1970. if (plane->state->pixel_blend_mode == DRM_MODE_BLEND_PREMULTI)
  1971. premulti_en = 1;
  1972. else
  1973. premulti_en = 0;
  1974. plane = &win->base;
  1975. fb = plane->state->fb;
  1976. pixel_alpha_en = fb->format->has_alpha;
  1977. alpha_config.src_premulti_en = premulti_en;
  1978. if (bottom_layer_alpha_en && zpos == 1) {
  1979. gpremulti_en = premulti_en;
  1980. /* Cd = Cs + (1 - As) * Cd * Agd */
  1981. alpha_config.dst_premulti_en = false;
  1982. alpha_config.src_pixel_alpha_en = pixel_alpha_en;
  1983. alpha_config.src_glb_alpha_value = plane->state->alpha;
  1984. alpha_config.dst_glb_alpha_value = dst_global_alpha;
  1985. } else if (vop2_cluster_window(win)) {
  1986. /* Mix output data only have pixel alpha */
  1987. alpha_config.dst_premulti_en = true;
  1988. alpha_config.src_pixel_alpha_en = true;
  1989. alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
  1990. alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
  1991. } else {
  1992. /* Cd = Cs + (1 - As) * Cd */
  1993. alpha_config.dst_premulti_en = true;
  1994. alpha_config.src_pixel_alpha_en = pixel_alpha_en;
  1995. alpha_config.src_glb_alpha_value = plane->state->alpha;
  1996. alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
  1997. }
  1998. vop2_parse_alpha(&alpha_config, &alpha);
  1999. offset = (mixer_id + zpos - 1) * 0x10;
  2000. vop2_writel(vop2, RK3568_MIX0_SRC_COLOR_CTRL + offset,
  2001. alpha.src_color_ctrl.val);
  2002. vop2_writel(vop2, RK3568_MIX0_DST_COLOR_CTRL + offset,
  2003. alpha.dst_color_ctrl.val);
  2004. vop2_writel(vop2, RK3568_MIX0_SRC_ALPHA_CTRL + offset,
  2005. alpha.src_alpha_ctrl.val);
  2006. vop2_writel(vop2, RK3568_MIX0_DST_ALPHA_CTRL + offset,
  2007. alpha.dst_alpha_ctrl.val);
  2008. }
  2009. if (vp->id == 0) {
  2010. if (bottom_layer_alpha_en) {
  2011. /* Transfer pixel alpha to hdr mix */
  2012. alpha_config.src_premulti_en = gpremulti_en;
  2013. alpha_config.dst_premulti_en = true;
  2014. alpha_config.src_pixel_alpha_en = true;
  2015. alpha_config.src_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
  2016. alpha_config.dst_glb_alpha_value = DRM_BLEND_ALPHA_OPAQUE;
  2017. vop2_parse_alpha(&alpha_config, &alpha);
  2018. vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL,
  2019. alpha.src_color_ctrl.val);
  2020. vop2_writel(vop2, RK3568_HDR0_DST_COLOR_CTRL,
  2021. alpha.dst_color_ctrl.val);
  2022. vop2_writel(vop2, RK3568_HDR0_SRC_ALPHA_CTRL,
  2023. alpha.src_alpha_ctrl.val);
  2024. vop2_writel(vop2, RK3568_HDR0_DST_ALPHA_CTRL,
  2025. alpha.dst_alpha_ctrl.val);
  2026. } else {
  2027. vop2_writel(vop2, RK3568_HDR0_SRC_COLOR_CTRL, 0);
  2028. }
  2029. }
  2030. }
  2031. static void vop2_setup_layer_mixer(struct vop2_video_port *vp)
  2032. {
  2033. struct vop2 *vop2 = vp->vop2;
  2034. struct drm_plane *plane;
  2035. u32 layer_sel = 0;
  2036. u32 port_sel;
  2037. u8 layer_id;
  2038. u8 old_layer_id;
  2039. u8 layer_sel_id;
  2040. unsigned int ofs;
  2041. u32 ovl_ctrl;
  2042. int i;
  2043. struct vop2_video_port *vp0 = &vop2->vps[0];
  2044. struct vop2_video_port *vp1 = &vop2->vps[1];
  2045. struct vop2_video_port *vp2 = &vop2->vps[2];
  2046. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(vp->crtc.state);
  2047. ovl_ctrl = vop2_readl(vop2, RK3568_OVL_CTRL);
  2048. ovl_ctrl |= RK3568_OVL_CTRL__LAYERSEL_REGDONE_IMD;
  2049. if (vcstate->yuv_overlay)
  2050. ovl_ctrl |= RK3568_OVL_CTRL__YUV_MODE(vp->id);
  2051. else
  2052. ovl_ctrl &= ~RK3568_OVL_CTRL__YUV_MODE(vp->id);
  2053. vop2_writel(vop2, RK3568_OVL_CTRL, ovl_ctrl);
  2054. port_sel = vop2_readl(vop2, RK3568_OVL_PORT_SEL);
  2055. port_sel &= RK3568_OVL_PORT_SEL__SEL_PORT;
  2056. if (vp0->nlayers)
  2057. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX,
  2058. vp0->nlayers - 1);
  2059. else
  2060. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT0_MUX, 8);
  2061. if (vp1->nlayers)
  2062. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX,
  2063. (vp0->nlayers + vp1->nlayers - 1));
  2064. else
  2065. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT1_MUX, 8);
  2066. if (vp2->nlayers)
  2067. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX,
  2068. (vp2->nlayers + vp1->nlayers + vp0->nlayers - 1));
  2069. else
  2070. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SET__PORT2_MUX, 8);
  2071. layer_sel = vop2_readl(vop2, RK3568_OVL_LAYER_SEL);
  2072. ofs = 0;
  2073. for (i = 0; i < vp->id; i++)
  2074. ofs += vop2->vps[i].nlayers;
  2075. drm_atomic_crtc_for_each_plane(plane, &vp->crtc) {
  2076. struct vop2_win *win = to_vop2_win(plane);
  2077. struct vop2_win *old_win;
  2078. layer_id = (u8)(plane->state->normalized_zpos + ofs);
  2079. /*
  2080. * Find the layer this win bind in old state.
  2081. */
  2082. for (old_layer_id = 0; old_layer_id < vop2->data->win_size; old_layer_id++) {
  2083. layer_sel_id = (layer_sel >> (4 * old_layer_id)) & 0xf;
  2084. if (layer_sel_id == win->data->layer_sel_id)
  2085. break;
  2086. }
  2087. /*
  2088. * Find the win bind to this layer in old state
  2089. */
  2090. for (i = 0; i < vop2->data->win_size; i++) {
  2091. old_win = &vop2->win[i];
  2092. layer_sel_id = (layer_sel >> (4 * layer_id)) & 0xf;
  2093. if (layer_sel_id == old_win->data->layer_sel_id)
  2094. break;
  2095. }
  2096. switch (win->data->phys_id) {
  2097. case ROCKCHIP_VOP2_CLUSTER0:
  2098. port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER0;
  2099. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER0, vp->id);
  2100. break;
  2101. case ROCKCHIP_VOP2_CLUSTER1:
  2102. port_sel &= ~RK3568_OVL_PORT_SEL__CLUSTER1;
  2103. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__CLUSTER1, vp->id);
  2104. break;
  2105. case ROCKCHIP_VOP2_CLUSTER2:
  2106. port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER2;
  2107. port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER2, vp->id);
  2108. break;
  2109. case ROCKCHIP_VOP2_CLUSTER3:
  2110. port_sel &= ~RK3588_OVL_PORT_SEL__CLUSTER3;
  2111. port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__CLUSTER3, vp->id);
  2112. break;
  2113. case ROCKCHIP_VOP2_ESMART0:
  2114. port_sel &= ~RK3568_OVL_PORT_SEL__ESMART0;
  2115. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART0, vp->id);
  2116. break;
  2117. case ROCKCHIP_VOP2_ESMART1:
  2118. port_sel &= ~RK3568_OVL_PORT_SEL__ESMART1;
  2119. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__ESMART1, vp->id);
  2120. break;
  2121. case ROCKCHIP_VOP2_ESMART2:
  2122. port_sel &= ~RK3588_OVL_PORT_SEL__ESMART2;
  2123. port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART2, vp->id);
  2124. break;
  2125. case ROCKCHIP_VOP2_ESMART3:
  2126. port_sel &= ~RK3588_OVL_PORT_SEL__ESMART3;
  2127. port_sel |= FIELD_PREP(RK3588_OVL_PORT_SEL__ESMART3, vp->id);
  2128. break;
  2129. case ROCKCHIP_VOP2_SMART0:
  2130. port_sel &= ~RK3568_OVL_PORT_SEL__SMART0;
  2131. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART0, vp->id);
  2132. break;
  2133. case ROCKCHIP_VOP2_SMART1:
  2134. port_sel &= ~RK3568_OVL_PORT_SEL__SMART1;
  2135. port_sel |= FIELD_PREP(RK3568_OVL_PORT_SEL__SMART1, vp->id);
  2136. break;
  2137. }
  2138. layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(layer_id, 0x7);
  2139. layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(layer_id, win->data->layer_sel_id);
  2140. /*
  2141. * When we bind a window from layerM to layerN, we also need to move the old
  2142. * window on layerN to layerM to avoid one window selected by two or more layers.
  2143. */
  2144. layer_sel &= ~RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, 0x7);
  2145. layer_sel |= RK3568_OVL_LAYER_SEL__LAYER(old_layer_id, old_win->data->layer_sel_id);
  2146. }
  2147. vop2_writel(vop2, RK3568_OVL_LAYER_SEL, layer_sel);
  2148. vop2_writel(vop2, RK3568_OVL_PORT_SEL, port_sel);
  2149. }
  2150. static void vop2_setup_dly_for_windows(struct vop2 *vop2)
  2151. {
  2152. struct vop2_win *win;
  2153. int i = 0;
  2154. u32 cdly = 0, sdly = 0;
  2155. for (i = 0; i < vop2->data->win_size; i++) {
  2156. u32 dly;
  2157. win = &vop2->win[i];
  2158. dly = win->delay;
  2159. switch (win->data->phys_id) {
  2160. case ROCKCHIP_VOP2_CLUSTER0:
  2161. cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_0, dly);
  2162. cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER0_1, dly);
  2163. break;
  2164. case ROCKCHIP_VOP2_CLUSTER1:
  2165. cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_0, dly);
  2166. cdly |= FIELD_PREP(RK3568_CLUSTER_DLY_NUM__CLUSTER1_1, dly);
  2167. break;
  2168. case ROCKCHIP_VOP2_ESMART0:
  2169. sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART0, dly);
  2170. break;
  2171. case ROCKCHIP_VOP2_ESMART1:
  2172. sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__ESMART1, dly);
  2173. break;
  2174. case ROCKCHIP_VOP2_SMART0:
  2175. case ROCKCHIP_VOP2_ESMART2:
  2176. sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART0, dly);
  2177. break;
  2178. case ROCKCHIP_VOP2_SMART1:
  2179. case ROCKCHIP_VOP2_ESMART3:
  2180. sdly |= FIELD_PREP(RK3568_SMART_DLY_NUM__SMART1, dly);
  2181. break;
  2182. }
  2183. }
  2184. vop2_writel(vop2, RK3568_CLUSTER_DLY_NUM, cdly);
  2185. vop2_writel(vop2, RK3568_SMART_DLY_NUM, sdly);
  2186. }
  2187. static void vop2_crtc_atomic_begin(struct drm_crtc *crtc,
  2188. struct drm_atomic_state *state)
  2189. {
  2190. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  2191. struct vop2 *vop2 = vp->vop2;
  2192. struct drm_plane *plane;
  2193. vp->win_mask = 0;
  2194. drm_atomic_crtc_for_each_plane(plane, crtc) {
  2195. struct vop2_win *win = to_vop2_win(plane);
  2196. win->delay = win->data->dly[VOP2_DLY_MODE_DEFAULT];
  2197. vp->win_mask |= BIT(win->data->phys_id);
  2198. if (vop2_cluster_window(win))
  2199. vop2_setup_cluster_alpha(vop2, win);
  2200. }
  2201. if (!vp->win_mask)
  2202. return;
  2203. vop2_setup_layer_mixer(vp);
  2204. vop2_setup_alpha(vp);
  2205. vop2_setup_dly_for_windows(vop2);
  2206. }
  2207. static void vop2_crtc_atomic_flush(struct drm_crtc *crtc,
  2208. struct drm_atomic_state *state)
  2209. {
  2210. struct vop2_video_port *vp = to_vop2_video_port(crtc);
  2211. vop2_post_config(crtc);
  2212. vop2_cfg_done(vp);
  2213. spin_lock_irq(&crtc->dev->event_lock);
  2214. if (crtc->state->event) {
  2215. WARN_ON(drm_crtc_vblank_get(crtc));
  2216. vp->event = crtc->state->event;
  2217. crtc->state->event = NULL;
  2218. }
  2219. spin_unlock_irq(&crtc->dev->event_lock);
  2220. }
  2221. static const struct drm_crtc_helper_funcs vop2_crtc_helper_funcs = {
  2222. .mode_fixup = vop2_crtc_mode_fixup,
  2223. .atomic_check = vop2_crtc_atomic_check,
  2224. .atomic_begin = vop2_crtc_atomic_begin,
  2225. .atomic_flush = vop2_crtc_atomic_flush,
  2226. .atomic_enable = vop2_crtc_atomic_enable,
  2227. .atomic_disable = vop2_crtc_atomic_disable,
  2228. };
  2229. static struct drm_crtc_state *vop2_crtc_duplicate_state(struct drm_crtc *crtc)
  2230. {
  2231. struct rockchip_crtc_state *vcstate;
  2232. if (WARN_ON(!crtc->state))
  2233. return NULL;
  2234. vcstate = kmemdup(to_rockchip_crtc_state(crtc->state),
  2235. sizeof(*vcstate), GFP_KERNEL);
  2236. if (!vcstate)
  2237. return NULL;
  2238. __drm_atomic_helper_crtc_duplicate_state(crtc, &vcstate->base);
  2239. return &vcstate->base;
  2240. }
  2241. static void vop2_crtc_destroy_state(struct drm_crtc *crtc,
  2242. struct drm_crtc_state *state)
  2243. {
  2244. struct rockchip_crtc_state *vcstate = to_rockchip_crtc_state(state);
  2245. __drm_atomic_helper_crtc_destroy_state(&vcstate->base);
  2246. kfree(vcstate);
  2247. }
  2248. static void vop2_crtc_reset(struct drm_crtc *crtc)
  2249. {
  2250. struct rockchip_crtc_state *vcstate =
  2251. kzalloc(sizeof(*vcstate), GFP_KERNEL);
  2252. if (crtc->state)
  2253. vop2_crtc_destroy_state(crtc, crtc->state);
  2254. if (vcstate)
  2255. __drm_atomic_helper_crtc_reset(crtc, &vcstate->base);
  2256. else
  2257. __drm_atomic_helper_crtc_reset(crtc, NULL);
  2258. }
  2259. static const struct drm_crtc_funcs vop2_crtc_funcs = {
  2260. .set_config = drm_atomic_helper_set_config,
  2261. .page_flip = drm_atomic_helper_page_flip,
  2262. .destroy = drm_crtc_cleanup,
  2263. .reset = vop2_crtc_reset,
  2264. .atomic_duplicate_state = vop2_crtc_duplicate_state,
  2265. .atomic_destroy_state = vop2_crtc_destroy_state,
  2266. .enable_vblank = vop2_crtc_enable_vblank,
  2267. .disable_vblank = vop2_crtc_disable_vblank,
  2268. };
  2269. static irqreturn_t vop2_isr(int irq, void *data)
  2270. {
  2271. struct vop2 *vop2 = data;
  2272. const struct vop2_data *vop2_data = vop2->data;
  2273. u32 axi_irqs[VOP2_SYS_AXI_BUS_NUM];
  2274. int ret = IRQ_NONE;
  2275. int i;
  2276. /*
  2277. * The irq is shared with the iommu. If the runtime-pm state of the
  2278. * vop2-device is disabled the irq has to be targeted at the iommu.
  2279. */
  2280. if (!pm_runtime_get_if_in_use(vop2->dev))
  2281. return IRQ_NONE;
  2282. for (i = 0; i < vop2_data->nr_vps; i++) {
  2283. struct vop2_video_port *vp = &vop2->vps[i];
  2284. struct drm_crtc *crtc = &vp->crtc;
  2285. u32 irqs;
  2286. irqs = vop2_readl(vop2, RK3568_VP_INT_STATUS(vp->id));
  2287. vop2_writel(vop2, RK3568_VP_INT_CLR(vp->id), irqs << 16 | irqs);
  2288. if (irqs & VP_INT_DSP_HOLD_VALID) {
  2289. complete(&vp->dsp_hold_completion);
  2290. ret = IRQ_HANDLED;
  2291. }
  2292. if (irqs & VP_INT_FS_FIELD) {
  2293. drm_crtc_handle_vblank(crtc);
  2294. spin_lock(&crtc->dev->event_lock);
  2295. if (vp->event) {
  2296. u32 val = vop2_readl(vop2, RK3568_REG_CFG_DONE);
  2297. if (!(val & BIT(vp->id))) {
  2298. drm_crtc_send_vblank_event(crtc, vp->event);
  2299. vp->event = NULL;
  2300. drm_crtc_vblank_put(crtc);
  2301. }
  2302. }
  2303. spin_unlock(&crtc->dev->event_lock);
  2304. ret = IRQ_HANDLED;
  2305. }
  2306. if (irqs & VP_INT_POST_BUF_EMPTY) {
  2307. drm_err_ratelimited(vop2->drm,
  2308. "POST_BUF_EMPTY irq err at vp%d\n",
  2309. vp->id);
  2310. ret = IRQ_HANDLED;
  2311. }
  2312. }
  2313. axi_irqs[0] = vop2_readl(vop2, RK3568_SYS0_INT_STATUS);
  2314. vop2_writel(vop2, RK3568_SYS0_INT_CLR, axi_irqs[0] << 16 | axi_irqs[0]);
  2315. axi_irqs[1] = vop2_readl(vop2, RK3568_SYS1_INT_STATUS);
  2316. vop2_writel(vop2, RK3568_SYS1_INT_CLR, axi_irqs[1] << 16 | axi_irqs[1]);
  2317. for (i = 0; i < ARRAY_SIZE(axi_irqs); i++) {
  2318. if (axi_irqs[i] & VOP2_INT_BUS_ERRPR) {
  2319. drm_err_ratelimited(vop2->drm, "BUS_ERROR irq err\n");
  2320. ret = IRQ_HANDLED;
  2321. }
  2322. }
  2323. pm_runtime_put(vop2->dev);
  2324. return ret;
  2325. }
  2326. static int vop2_plane_init(struct vop2 *vop2, struct vop2_win *win,
  2327. unsigned long possible_crtcs)
  2328. {
  2329. const struct vop2_win_data *win_data = win->data;
  2330. unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
  2331. BIT(DRM_MODE_BLEND_PREMULTI) |
  2332. BIT(DRM_MODE_BLEND_COVERAGE);
  2333. int ret;
  2334. ret = drm_universal_plane_init(vop2->drm, &win->base, possible_crtcs,
  2335. &vop2_plane_funcs, win_data->formats,
  2336. win_data->nformats,
  2337. win_data->format_modifiers,
  2338. win->type, win_data->name);
  2339. if (ret) {
  2340. drm_err(vop2->drm, "failed to initialize plane %d\n", ret);
  2341. return ret;
  2342. }
  2343. drm_plane_helper_add(&win->base, &vop2_plane_helper_funcs);
  2344. if (win->data->supported_rotations)
  2345. drm_plane_create_rotation_property(&win->base, DRM_MODE_ROTATE_0,
  2346. DRM_MODE_ROTATE_0 |
  2347. win->data->supported_rotations);
  2348. drm_plane_create_alpha_property(&win->base);
  2349. drm_plane_create_blend_mode_property(&win->base, blend_caps);
  2350. drm_plane_create_zpos_property(&win->base, win->win_id, 0,
  2351. vop2->registered_num_wins - 1);
  2352. return 0;
  2353. }
  2354. static struct vop2_video_port *find_vp_without_primary(struct vop2 *vop2)
  2355. {
  2356. int i;
  2357. for (i = 0; i < vop2->data->nr_vps; i++) {
  2358. struct vop2_video_port *vp = &vop2->vps[i];
  2359. if (!vp->crtc.port)
  2360. continue;
  2361. if (vp->primary_plane)
  2362. continue;
  2363. return vp;
  2364. }
  2365. return NULL;
  2366. }
  2367. static int vop2_create_crtcs(struct vop2 *vop2)
  2368. {
  2369. const struct vop2_data *vop2_data = vop2->data;
  2370. struct drm_device *drm = vop2->drm;
  2371. struct device *dev = vop2->dev;
  2372. struct drm_plane *plane;
  2373. struct device_node *port;
  2374. struct vop2_video_port *vp;
  2375. int i, nvp, nvps = 0;
  2376. int ret;
  2377. for (i = 0; i < vop2_data->nr_vps; i++) {
  2378. const struct vop2_video_port_data *vp_data;
  2379. struct device_node *np;
  2380. char dclk_name[9];
  2381. vp_data = &vop2_data->vp[i];
  2382. vp = &vop2->vps[i];
  2383. vp->vop2 = vop2;
  2384. vp->id = vp_data->id;
  2385. vp->data = vp_data;
  2386. snprintf(dclk_name, sizeof(dclk_name), "dclk_vp%d", vp->id);
  2387. vp->dclk = devm_clk_get(vop2->dev, dclk_name);
  2388. if (IS_ERR(vp->dclk)) {
  2389. drm_err(vop2->drm, "failed to get %s\n", dclk_name);
  2390. return PTR_ERR(vp->dclk);
  2391. }
  2392. np = of_graph_get_remote_node(dev->of_node, i, -1);
  2393. if (!np) {
  2394. drm_dbg(vop2->drm, "%s: No remote for vp%d\n", __func__, i);
  2395. continue;
  2396. }
  2397. of_node_put(np);
  2398. port = of_graph_get_port_by_id(dev->of_node, i);
  2399. if (!port) {
  2400. drm_err(vop2->drm, "no port node found for video_port%d\n", i);
  2401. return -ENOENT;
  2402. }
  2403. vp->crtc.port = port;
  2404. nvps++;
  2405. }
  2406. nvp = 0;
  2407. for (i = 0; i < vop2->registered_num_wins; i++) {
  2408. struct vop2_win *win = &vop2->win[i];
  2409. u32 possible_crtcs = 0;
  2410. if (vop2->data->soc_id == 3566) {
  2411. /*
  2412. * On RK3566 these windows don't have an independent
  2413. * framebuffer. They share the framebuffer with smart0,
  2414. * esmart0 and cluster0 respectively.
  2415. */
  2416. switch (win->data->phys_id) {
  2417. case ROCKCHIP_VOP2_SMART1:
  2418. case ROCKCHIP_VOP2_ESMART1:
  2419. case ROCKCHIP_VOP2_CLUSTER1:
  2420. continue;
  2421. }
  2422. }
  2423. if (win->type == DRM_PLANE_TYPE_PRIMARY) {
  2424. vp = find_vp_without_primary(vop2);
  2425. if (vp) {
  2426. possible_crtcs = BIT(nvp);
  2427. vp->primary_plane = win;
  2428. nvp++;
  2429. } else {
  2430. /* change the unused primary window to overlay window */
  2431. win->type = DRM_PLANE_TYPE_OVERLAY;
  2432. }
  2433. }
  2434. if (win->type == DRM_PLANE_TYPE_OVERLAY)
  2435. possible_crtcs = (1 << nvps) - 1;
  2436. ret = vop2_plane_init(vop2, win, possible_crtcs);
  2437. if (ret) {
  2438. drm_err(vop2->drm, "failed to init plane %s: %d\n",
  2439. win->data->name, ret);
  2440. return ret;
  2441. }
  2442. }
  2443. for (i = 0; i < vop2_data->nr_vps; i++) {
  2444. vp = &vop2->vps[i];
  2445. if (!vp->crtc.port)
  2446. continue;
  2447. plane = &vp->primary_plane->base;
  2448. ret = drm_crtc_init_with_planes(drm, &vp->crtc, plane, NULL,
  2449. &vop2_crtc_funcs,
  2450. "video_port%d", vp->id);
  2451. if (ret) {
  2452. drm_err(vop2->drm, "crtc init for video_port%d failed\n", i);
  2453. return ret;
  2454. }
  2455. drm_crtc_helper_add(&vp->crtc, &vop2_crtc_helper_funcs);
  2456. init_completion(&vp->dsp_hold_completion);
  2457. }
  2458. /*
  2459. * On the VOP2 it's very hard to change the number of layers on a VP
  2460. * during runtime, so we distribute the layers equally over the used
  2461. * VPs
  2462. */
  2463. for (i = 0; i < vop2->data->nr_vps; i++) {
  2464. struct vop2_video_port *vp = &vop2->vps[i];
  2465. if (vp->crtc.port)
  2466. vp->nlayers = vop2_data->win_size / nvps;
  2467. }
  2468. return 0;
  2469. }
  2470. static void vop2_destroy_crtcs(struct vop2 *vop2)
  2471. {
  2472. struct drm_device *drm = vop2->drm;
  2473. struct list_head *crtc_list = &drm->mode_config.crtc_list;
  2474. struct list_head *plane_list = &drm->mode_config.plane_list;
  2475. struct drm_crtc *crtc, *tmpc;
  2476. struct drm_plane *plane, *tmpp;
  2477. list_for_each_entry_safe(plane, tmpp, plane_list, head)
  2478. drm_plane_cleanup(plane);
  2479. /*
  2480. * Destroy CRTC after vop2_plane_destroy() since vop2_disable_plane()
  2481. * references the CRTC.
  2482. */
  2483. list_for_each_entry_safe(crtc, tmpc, crtc_list, head) {
  2484. of_node_put(crtc->port);
  2485. drm_crtc_cleanup(crtc);
  2486. }
  2487. }
  2488. static int vop2_find_rgb_encoder(struct vop2 *vop2)
  2489. {
  2490. struct device_node *node = vop2->dev->of_node;
  2491. struct device_node *endpoint;
  2492. int i;
  2493. for (i = 0; i < vop2->data->nr_vps; i++) {
  2494. endpoint = of_graph_get_endpoint_by_regs(node, i,
  2495. ROCKCHIP_VOP2_EP_RGB0);
  2496. if (!endpoint)
  2497. continue;
  2498. of_node_put(endpoint);
  2499. return i;
  2500. }
  2501. return -ENOENT;
  2502. }
  2503. static struct reg_field vop2_cluster_regs[VOP2_WIN_MAX_REG] = {
  2504. [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 0, 0),
  2505. [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 1, 5),
  2506. [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 14, 14),
  2507. [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 18, 18),
  2508. [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_ACT_INFO, 0, 31),
  2509. [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_INFO, 0, 31),
  2510. [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_CLUSTER_WIN_DSP_ST, 0, 31),
  2511. [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_CLUSTER_WIN_YRGB_MST, 0, 31),
  2512. [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_CLUSTER_WIN_CBR_MST, 0, 31),
  2513. [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 19, 19),
  2514. [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 0, 15),
  2515. [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_CLUSTER_WIN_VIR, 16, 31),
  2516. [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 8, 8),
  2517. [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 9, 9),
  2518. [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL0, 10, 11),
  2519. [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 0, 3),
  2520. [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL2, 5, 8),
  2521. /* RK3588 only, reserved bit on rk3568*/
  2522. [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3568_CLUSTER_CTRL, 13, 13),
  2523. /* Scale */
  2524. [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 0, 15),
  2525. [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_CLUSTER_WIN_SCL_FACTOR_YRGB, 16, 31),
  2526. [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 14, 15),
  2527. [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 12, 13),
  2528. [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 2, 3),
  2529. [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 28, 28),
  2530. [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_CLUSTER_WIN_CTRL1, 29, 29),
  2531. /* cluster regs */
  2532. [VOP2_WIN_AFBC_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 1, 1),
  2533. [VOP2_WIN_CLUSTER_ENABLE] = REG_FIELD(RK3568_CLUSTER_CTRL, 0, 0),
  2534. [VOP2_WIN_CLUSTER_LB_MODE] = REG_FIELD(RK3568_CLUSTER_CTRL, 4, 7),
  2535. /* afbc regs */
  2536. [VOP2_WIN_AFBC_FORMAT] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 2, 6),
  2537. [VOP2_WIN_AFBC_RB_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 9, 9),
  2538. [VOP2_WIN_AFBC_UV_SWAP] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 10, 10),
  2539. [VOP2_WIN_AFBC_AUTO_GATING_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_OUTPUT_CTRL, 4, 4),
  2540. [VOP2_WIN_AFBC_HALF_BLOCK_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 7, 7),
  2541. [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_CTRL, 8, 8),
  2542. [VOP2_WIN_AFBC_HDR_PTR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_HDR_PTR, 0, 31),
  2543. [VOP2_WIN_AFBC_PIC_SIZE] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_SIZE, 0, 31),
  2544. [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 0, 15),
  2545. [VOP2_WIN_AFBC_TILE_NUM] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_VIR_WIDTH, 16, 31),
  2546. [VOP2_WIN_AFBC_PIC_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_PIC_OFFSET, 0, 31),
  2547. [VOP2_WIN_AFBC_DSP_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_DSP_OFFSET, 0, 31),
  2548. [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_TRANSFORM_OFFSET, 0, 31),
  2549. [VOP2_WIN_AFBC_ROTATE_90] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 0, 0),
  2550. [VOP2_WIN_AFBC_ROTATE_270] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 1, 1),
  2551. [VOP2_WIN_XMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 2, 2),
  2552. [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_CLUSTER_WIN_AFBCD_ROTATE_MODE, 3, 3),
  2553. [VOP2_WIN_UV_SWAP] = { .reg = 0xffffffff },
  2554. [VOP2_WIN_COLOR_KEY] = { .reg = 0xffffffff },
  2555. [VOP2_WIN_COLOR_KEY_EN] = { .reg = 0xffffffff },
  2556. [VOP2_WIN_SCALE_CBCR_X] = { .reg = 0xffffffff },
  2557. [VOP2_WIN_SCALE_CBCR_Y] = { .reg = 0xffffffff },
  2558. [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
  2559. [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
  2560. [VOP2_WIN_CBCR_VER_SCL_MODE] = { .reg = 0xffffffff },
  2561. [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = { .reg = 0xffffffff },
  2562. [VOP2_WIN_CBCR_HOR_SCL_MODE] = { .reg = 0xffffffff },
  2563. [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = { .reg = 0xffffffff },
  2564. [VOP2_WIN_VSD_CBCR_GT2] = { .reg = 0xffffffff },
  2565. [VOP2_WIN_VSD_CBCR_GT4] = { .reg = 0xffffffff },
  2566. };
  2567. static int vop2_cluster_init(struct vop2_win *win)
  2568. {
  2569. struct vop2 *vop2 = win->vop2;
  2570. struct reg_field *cluster_regs;
  2571. int ret, i;
  2572. cluster_regs = kmemdup(vop2_cluster_regs, sizeof(vop2_cluster_regs),
  2573. GFP_KERNEL);
  2574. if (!cluster_regs)
  2575. return -ENOMEM;
  2576. for (i = 0; i < ARRAY_SIZE(vop2_cluster_regs); i++)
  2577. if (cluster_regs[i].reg != 0xffffffff)
  2578. cluster_regs[i].reg += win->offset;
  2579. ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
  2580. cluster_regs,
  2581. ARRAY_SIZE(vop2_cluster_regs));
  2582. kfree(cluster_regs);
  2583. return ret;
  2584. };
  2585. static struct reg_field vop2_esmart_regs[VOP2_WIN_MAX_REG] = {
  2586. [VOP2_WIN_ENABLE] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 0, 0),
  2587. [VOP2_WIN_FORMAT] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 1, 5),
  2588. [VOP2_WIN_DITHER_UP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 12, 12),
  2589. [VOP2_WIN_RB_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 14, 14),
  2590. [VOP2_WIN_UV_SWAP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 16, 16),
  2591. [VOP2_WIN_ACT_INFO] = REG_FIELD(RK3568_SMART_REGION0_ACT_INFO, 0, 31),
  2592. [VOP2_WIN_DSP_INFO] = REG_FIELD(RK3568_SMART_REGION0_DSP_INFO, 0, 31),
  2593. [VOP2_WIN_DSP_ST] = REG_FIELD(RK3568_SMART_REGION0_DSP_ST, 0, 28),
  2594. [VOP2_WIN_YRGB_MST] = REG_FIELD(RK3568_SMART_REGION0_YRGB_MST, 0, 31),
  2595. [VOP2_WIN_UV_MST] = REG_FIELD(RK3568_SMART_REGION0_CBR_MST, 0, 31),
  2596. [VOP2_WIN_YUV_CLIP] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 17, 17),
  2597. [VOP2_WIN_YRGB_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 0, 15),
  2598. [VOP2_WIN_UV_VIR] = REG_FIELD(RK3568_SMART_REGION0_VIR, 16, 31),
  2599. [VOP2_WIN_Y2R_EN] = REG_FIELD(RK3568_SMART_CTRL0, 0, 0),
  2600. [VOP2_WIN_R2Y_EN] = REG_FIELD(RK3568_SMART_CTRL0, 1, 1),
  2601. [VOP2_WIN_CSC_MODE] = REG_FIELD(RK3568_SMART_CTRL0, 2, 3),
  2602. [VOP2_WIN_YMIRROR] = REG_FIELD(RK3568_SMART_CTRL1, 31, 31),
  2603. [VOP2_WIN_COLOR_KEY] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 0, 29),
  2604. [VOP2_WIN_COLOR_KEY_EN] = REG_FIELD(RK3568_SMART_COLOR_KEY_CTRL, 31, 31),
  2605. [VOP2_WIN_AXI_YRGB_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 4, 8),
  2606. [VOP2_WIN_AXI_UV_R_ID] = REG_FIELD(RK3568_SMART_CTRL1, 12, 16),
  2607. /* RK3588 only, reserved register on rk3568 */
  2608. [VOP2_WIN_AXI_BUS_ID] = REG_FIELD(RK3588_SMART_AXI_CTRL, 1, 1),
  2609. /* Scale */
  2610. [VOP2_WIN_SCALE_YRGB_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 0, 15),
  2611. [VOP2_WIN_SCALE_YRGB_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_YRGB, 16, 31),
  2612. [VOP2_WIN_SCALE_CBCR_X] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 0, 15),
  2613. [VOP2_WIN_SCALE_CBCR_Y] = REG_FIELD(RK3568_SMART_REGION0_SCL_FACTOR_CBR, 16, 31),
  2614. [VOP2_WIN_YRGB_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 0, 1),
  2615. [VOP2_WIN_YRGB_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 2, 3),
  2616. [VOP2_WIN_YRGB_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 4, 5),
  2617. [VOP2_WIN_YRGB_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 6, 7),
  2618. [VOP2_WIN_CBCR_HOR_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 8, 9),
  2619. [VOP2_WIN_CBCR_HSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 10, 11),
  2620. [VOP2_WIN_CBCR_VER_SCL_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 12, 13),
  2621. [VOP2_WIN_CBCR_VSCL_FILTER_MODE] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 14, 15),
  2622. [VOP2_WIN_BIC_COE_SEL] = REG_FIELD(RK3568_SMART_REGION0_SCL_CTRL, 16, 17),
  2623. [VOP2_WIN_VSD_YRGB_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 8, 8),
  2624. [VOP2_WIN_VSD_YRGB_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 9, 9),
  2625. [VOP2_WIN_VSD_CBCR_GT2] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 10, 10),
  2626. [VOP2_WIN_VSD_CBCR_GT4] = REG_FIELD(RK3568_SMART_REGION0_CTRL, 11, 11),
  2627. [VOP2_WIN_XMIRROR] = { .reg = 0xffffffff },
  2628. [VOP2_WIN_CLUSTER_ENABLE] = { .reg = 0xffffffff },
  2629. [VOP2_WIN_AFBC_ENABLE] = { .reg = 0xffffffff },
  2630. [VOP2_WIN_CLUSTER_LB_MODE] = { .reg = 0xffffffff },
  2631. [VOP2_WIN_AFBC_FORMAT] = { .reg = 0xffffffff },
  2632. [VOP2_WIN_AFBC_RB_SWAP] = { .reg = 0xffffffff },
  2633. [VOP2_WIN_AFBC_UV_SWAP] = { .reg = 0xffffffff },
  2634. [VOP2_WIN_AFBC_AUTO_GATING_EN] = { .reg = 0xffffffff },
  2635. [VOP2_WIN_AFBC_BLOCK_SPLIT_EN] = { .reg = 0xffffffff },
  2636. [VOP2_WIN_AFBC_PIC_VIR_WIDTH] = { .reg = 0xffffffff },
  2637. [VOP2_WIN_AFBC_TILE_NUM] = { .reg = 0xffffffff },
  2638. [VOP2_WIN_AFBC_PIC_OFFSET] = { .reg = 0xffffffff },
  2639. [VOP2_WIN_AFBC_PIC_SIZE] = { .reg = 0xffffffff },
  2640. [VOP2_WIN_AFBC_DSP_OFFSET] = { .reg = 0xffffffff },
  2641. [VOP2_WIN_AFBC_TRANSFORM_OFFSET] = { .reg = 0xffffffff },
  2642. [VOP2_WIN_AFBC_HDR_PTR] = { .reg = 0xffffffff },
  2643. [VOP2_WIN_AFBC_HALF_BLOCK_EN] = { .reg = 0xffffffff },
  2644. [VOP2_WIN_AFBC_ROTATE_270] = { .reg = 0xffffffff },
  2645. [VOP2_WIN_AFBC_ROTATE_90] = { .reg = 0xffffffff },
  2646. };
  2647. static int vop2_esmart_init(struct vop2_win *win)
  2648. {
  2649. struct vop2 *vop2 = win->vop2;
  2650. struct reg_field *esmart_regs;
  2651. int ret, i;
  2652. esmart_regs = kmemdup(vop2_esmart_regs, sizeof(vop2_esmart_regs),
  2653. GFP_KERNEL);
  2654. if (!esmart_regs)
  2655. return -ENOMEM;
  2656. for (i = 0; i < ARRAY_SIZE(vop2_esmart_regs); i++)
  2657. if (esmart_regs[i].reg != 0xffffffff)
  2658. esmart_regs[i].reg += win->offset;
  2659. ret = devm_regmap_field_bulk_alloc(vop2->dev, vop2->map, win->reg,
  2660. esmart_regs,
  2661. ARRAY_SIZE(vop2_esmart_regs));
  2662. kfree(esmart_regs);
  2663. return ret;
  2664. };
  2665. static int vop2_win_init(struct vop2 *vop2)
  2666. {
  2667. const struct vop2_data *vop2_data = vop2->data;
  2668. struct vop2_win *win;
  2669. int i, ret;
  2670. for (i = 0; i < vop2_data->win_size; i++) {
  2671. const struct vop2_win_data *win_data = &vop2_data->win[i];
  2672. win = &vop2->win[i];
  2673. win->data = win_data;
  2674. win->type = win_data->type;
  2675. win->offset = win_data->base;
  2676. win->win_id = i;
  2677. win->vop2 = vop2;
  2678. if (vop2_cluster_window(win))
  2679. ret = vop2_cluster_init(win);
  2680. else
  2681. ret = vop2_esmart_init(win);
  2682. if (ret)
  2683. return ret;
  2684. }
  2685. vop2->registered_num_wins = vop2_data->win_size;
  2686. return 0;
  2687. }
  2688. /*
  2689. * The window registers are only updated when config done is written.
  2690. * Until that they read back the old value. As we read-modify-write
  2691. * these registers mark them as non-volatile. This makes sure we read
  2692. * the new values from the regmap register cache.
  2693. */
  2694. static const struct regmap_range vop2_nonvolatile_range[] = {
  2695. regmap_reg_range(0x1000, 0x23ff),
  2696. };
  2697. static const struct regmap_access_table vop2_volatile_table = {
  2698. .no_ranges = vop2_nonvolatile_range,
  2699. .n_no_ranges = ARRAY_SIZE(vop2_nonvolatile_range),
  2700. };
  2701. static const struct regmap_config vop2_regmap_config = {
  2702. .reg_bits = 32,
  2703. .val_bits = 32,
  2704. .reg_stride = 4,
  2705. .max_register = 0x3000,
  2706. .name = "vop2",
  2707. .volatile_table = &vop2_volatile_table,
  2708. .cache_type = REGCACHE_MAPLE,
  2709. };
  2710. static int vop2_bind(struct device *dev, struct device *master, void *data)
  2711. {
  2712. struct platform_device *pdev = to_platform_device(dev);
  2713. const struct vop2_data *vop2_data;
  2714. struct drm_device *drm = data;
  2715. struct vop2 *vop2;
  2716. struct resource *res;
  2717. size_t alloc_size;
  2718. int ret;
  2719. vop2_data = of_device_get_match_data(dev);
  2720. if (!vop2_data)
  2721. return -ENODEV;
  2722. /* Allocate vop2 struct and its vop2_win array */
  2723. alloc_size = struct_size(vop2, win, vop2_data->win_size);
  2724. vop2 = devm_kzalloc(dev, alloc_size, GFP_KERNEL);
  2725. if (!vop2)
  2726. return -ENOMEM;
  2727. vop2->dev = dev;
  2728. vop2->data = vop2_data;
  2729. vop2->drm = drm;
  2730. dev_set_drvdata(dev, vop2);
  2731. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vop");
  2732. if (!res) {
  2733. drm_err(vop2->drm, "failed to get vop2 register byname\n");
  2734. return -EINVAL;
  2735. }
  2736. vop2->regs = devm_ioremap_resource(dev, res);
  2737. if (IS_ERR(vop2->regs))
  2738. return PTR_ERR(vop2->regs);
  2739. vop2->len = resource_size(res);
  2740. vop2->map = devm_regmap_init_mmio(dev, vop2->regs, &vop2_regmap_config);
  2741. if (IS_ERR(vop2->map))
  2742. return PTR_ERR(vop2->map);
  2743. ret = vop2_win_init(vop2);
  2744. if (ret)
  2745. return ret;
  2746. res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "gamma-lut");
  2747. if (res) {
  2748. vop2->lut_regs = devm_ioremap_resource(dev, res);
  2749. if (IS_ERR(vop2->lut_regs))
  2750. return PTR_ERR(vop2->lut_regs);
  2751. }
  2752. if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_GRF) {
  2753. vop2->sys_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,grf");
  2754. if (IS_ERR(vop2->sys_grf))
  2755. return dev_err_probe(dev, PTR_ERR(vop2->sys_grf), "cannot get sys_grf");
  2756. }
  2757. if (vop2_data->feature & VOP2_FEATURE_HAS_VOP_GRF) {
  2758. vop2->vop_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vop-grf");
  2759. if (IS_ERR(vop2->vop_grf))
  2760. return dev_err_probe(dev, PTR_ERR(vop2->vop_grf), "cannot get vop_grf");
  2761. }
  2762. if (vop2_data->feature & VOP2_FEATURE_HAS_VO1_GRF) {
  2763. vop2->vo1_grf = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,vo1-grf");
  2764. if (IS_ERR(vop2->vo1_grf))
  2765. return dev_err_probe(dev, PTR_ERR(vop2->vo1_grf), "cannot get vo1_grf");
  2766. }
  2767. if (vop2_data->feature & VOP2_FEATURE_HAS_SYS_PMU) {
  2768. vop2->sys_pmu = syscon_regmap_lookup_by_phandle(dev->of_node, "rockchip,pmu");
  2769. if (IS_ERR(vop2->sys_pmu))
  2770. return dev_err_probe(dev, PTR_ERR(vop2->sys_pmu), "cannot get sys_pmu");
  2771. }
  2772. vop2->hclk = devm_clk_get(vop2->dev, "hclk");
  2773. if (IS_ERR(vop2->hclk)) {
  2774. drm_err(vop2->drm, "failed to get hclk source\n");
  2775. return PTR_ERR(vop2->hclk);
  2776. }
  2777. vop2->aclk = devm_clk_get(vop2->dev, "aclk");
  2778. if (IS_ERR(vop2->aclk)) {
  2779. drm_err(vop2->drm, "failed to get aclk source\n");
  2780. return PTR_ERR(vop2->aclk);
  2781. }
  2782. vop2->pclk = devm_clk_get_optional(vop2->dev, "pclk_vop");
  2783. if (IS_ERR(vop2->pclk)) {
  2784. drm_err(vop2->drm, "failed to get pclk source\n");
  2785. return PTR_ERR(vop2->pclk);
  2786. }
  2787. vop2->pll_hdmiphy0 = devm_clk_get_optional(vop2->dev, "pll_hdmiphy0");
  2788. if (IS_ERR(vop2->pll_hdmiphy0)) {
  2789. drm_err(vop2->drm, "failed to get pll_hdmiphy0\n");
  2790. return PTR_ERR(vop2->pll_hdmiphy0);
  2791. }
  2792. vop2->irq = platform_get_irq(pdev, 0);
  2793. if (vop2->irq < 0) {
  2794. drm_err(vop2->drm, "cannot find irq for vop2\n");
  2795. return vop2->irq;
  2796. }
  2797. mutex_init(&vop2->vop2_lock);
  2798. ret = devm_request_irq(dev, vop2->irq, vop2_isr, IRQF_SHARED, dev_name(dev), vop2);
  2799. if (ret)
  2800. return ret;
  2801. ret = vop2_create_crtcs(vop2);
  2802. if (ret)
  2803. return ret;
  2804. ret = vop2_find_rgb_encoder(vop2);
  2805. if (ret >= 0) {
  2806. vop2->rgb = rockchip_rgb_init(dev, &vop2->vps[ret].crtc,
  2807. vop2->drm, ret);
  2808. if (IS_ERR(vop2->rgb)) {
  2809. if (PTR_ERR(vop2->rgb) == -EPROBE_DEFER) {
  2810. ret = PTR_ERR(vop2->rgb);
  2811. goto err_crtcs;
  2812. }
  2813. vop2->rgb = NULL;
  2814. }
  2815. }
  2816. rockchip_drm_dma_init_device(vop2->drm, vop2->dev);
  2817. pm_runtime_enable(&pdev->dev);
  2818. return 0;
  2819. err_crtcs:
  2820. vop2_destroy_crtcs(vop2);
  2821. return ret;
  2822. }
  2823. static void vop2_unbind(struct device *dev, struct device *master, void *data)
  2824. {
  2825. struct vop2 *vop2 = dev_get_drvdata(dev);
  2826. pm_runtime_disable(dev);
  2827. if (vop2->rgb)
  2828. rockchip_rgb_fini(vop2->rgb);
  2829. vop2_destroy_crtcs(vop2);
  2830. }
  2831. const struct component_ops vop2_component_ops = {
  2832. .bind = vop2_bind,
  2833. .unbind = vop2_unbind,
  2834. };
  2835. EXPORT_SYMBOL_GPL(vop2_component_ops);