From d1aeebac347e6322786e6952ec29211580328679 Mon Sep 17 00:00:00 2001 From: Shantanu Gupta Date: Thu, 3 May 2012 12:08:24 +0530 Subject: [PATCH 1/6] [KGSL] remove the older driver along with some apparently unused, unrequired binaries. --- arch/arm/configs/htcleo_defconfig | 2 - drivers/video/msm/Kconfig | 16 - drivers/video/msm/Makefile | 2 - .../msm/gpu/KGSL_SI/Untitled Project.IAB | Bin 102400 -> 0 bytes .../msm/gpu/KGSL_SI/Untitled Project.IAD | Bin 1328 -> 0 bytes .../msm/gpu/KGSL_SI/Untitled Project.IMB | Bin 28672 -> 0 bytes .../msm/gpu/KGSL_SI/Untitled Project.IMD | Bin 608 -> 0 bytes .../msm/gpu/KGSL_SI/Untitled Project.PFI | Bin 72 -> 0 bytes .../video/msm/gpu/KGSL_SI/Untitled Project.PO | Bin 776 -> 0 bytes .../video/msm/gpu/KGSL_SI/Untitled Project.PR | Bin 6128 -> 0 bytes .../msm/gpu/KGSL_SI/Untitled Project.PRI | Bin 36944 -> 0 bytes .../video/msm/gpu/KGSL_SI/Untitled Project.PS | Bin 186272 -> 0 bytes .../KGSL_SI/Untitled Project.SearchResults | 12 - drivers/video/msm/gpu/kgsl/Makefile | 11 - drivers/video/msm/gpu/kgsl/kgsl.c | 1228 ----------- drivers/video/msm/gpu/kgsl/kgsl.h | 84 - drivers/video/msm/gpu/kgsl/kgsl_cmdstream.c | 105 - drivers/video/msm/gpu/kgsl/kgsl_cmdstream.h | 54 - drivers/video/msm/gpu/kgsl/kgsl_device.h | 141 -- drivers/video/msm/gpu/kgsl/kgsl_drawctxt.c | 1823 ----------------- drivers/video/msm/gpu/kgsl/kgsl_drawctxt.h | 120 -- drivers/video/msm/gpu/kgsl/kgsl_log.c | 292 --- drivers/video/msm/gpu/kgsl/kgsl_log.h | 105 - drivers/video/msm/gpu/kgsl/kgsl_mmu.c | 672 ------ drivers/video/msm/gpu/kgsl/kgsl_mmu.h | 169 -- drivers/video/msm/gpu/kgsl/kgsl_pm4types.h | 182 -- drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c | 837 -------- drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.h | 254 --- drivers/video/msm/gpu/kgsl/kgsl_sharedmem.c | 300 --- drivers/video/msm/gpu/kgsl/kgsl_sharedmem.h | 111 - drivers/video/msm/gpu/kgsl/kgsl_yamato.c | 1004 --------- drivers/video/msm/gpu/kgsl/yamato_reg.h | 400 ---- 32 files changed, 7924 deletions(-) delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAB delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAD delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMB delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMD delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.PFI delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.PO delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.PR delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.PRI delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.PS delete mode 100755 drivers/video/msm/gpu/KGSL_SI/Untitled Project.SearchResults delete mode 100644 drivers/video/msm/gpu/kgsl/Makefile delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_cmdstream.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_cmdstream.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_device.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_drawctxt.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_drawctxt.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_log.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_log.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_mmu.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_mmu.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_pm4types.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_sharedmem.c delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_sharedmem.h delete mode 100644 drivers/video/msm/gpu/kgsl/kgsl_yamato.c delete mode 100644 drivers/video/msm/gpu/kgsl/yamato_reg.h diff --git a/arch/arm/configs/htcleo_defconfig b/arch/arm/configs/htcleo_defconfig index 5cfd40dd..5f799b34 100644 --- a/arch/arm/configs/htcleo_defconfig +++ b/arch/arm/configs/htcleo_defconfig @@ -1407,8 +1407,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y CONFIG_FB_MSM=y CONFIG_FB_MSM_LCDC=y # CONFIG_FB_MSM_TVOUT is not set -# CONFIG_GPU_MSM_KGSL is not set -# CONFIG_GPU_MSM_KGSL_MMU is not set # CONFIG_MSM_HDMI is not set CONFIG_FB_MSM_LOGO=y # CONFIG_BACKLIGHT_LCD_SUPPORT is not set diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig index 9ce28950..c6610107 100644 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -55,22 +55,6 @@ config MSM_ROTATOR_USE_IMEM block. Or some systems may want the iMem to be dedicated to a different function. -config GPU_MSM_KGSL_MMU - bool "Turn on MMU for graphics driver " - depends on GPU_MSM_KGSL && MMU - default n - help - If enabled, the GPU driver will allocate memory from vmalloc - and enable the use of GPU MMU, instead of using pmem. - -config MSM_KGSL_PER_FD_PAGETABLE - bool "Turn on per-fd pagetable for MMU of graphics driver " - depends on MSM_KGSL_MMU && MMU - default n - help - If enabled, the MMU unit of GPU driver will use seperate - pagetables for each file descriptor - config MSM_HDMI bool "Support for HDMI in QCT platform" depends on MSM_MDP31 diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile index a013cd57..60380b65 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -33,5 +33,3 @@ obj-y += mddi_client_novb9f6_5582.o obj-$(CONFIG_FB_MSM_LCDC) += mdp_lcdc.o obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o tvfb.o -# Yamato GL driver -obj-$(CONFIG_GPU_MSM_KGSL) += gpu/kgsl/ diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAB b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAB deleted file mode 100755 index e8d88646ee63d2f96ff940ea24fcb2c5212faa27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 102400 zcmeI#&2Lmy7{~F`nSmH63xXy_G)g3biY5}&mEfI$!laW9nHQvqT1$t*z|c|J0)mTK z_-;@EF~)@^M&%vKyOJ0dL^c?R3nMOki4ch~nux}QZhX#}bLL*2zu`Lxw7)#(^>feM zd;4SBOg8el-I!Js8S|6M$CEkNYp$z&YbMcO>I;pTZpXV>{zXG$^^jAN2PH33^%s1W z`Ca>0O=mn4Dj!z)h{`*~(~`;hP1LBbITqLL{+1qBc|zsww!3`X^_2EURo&K7nd$BG z)@ZaF%m42DN!~5yvuFITdFUEniYPt@25ghmz-`lr=S#SF5~Ec2+iwJO(D4(ko$tylGi${SR^=(D?ivcFmB_VtkQT2a}UyH$Qv<%KFQ zQu%R}Bb9qqF8l1xo6KKT`3aT#Ri4w8IFFS|X|Brms(hcy_p5wIN{+L9bq83|9@f409qq5TJ{{*lUud=Bj=R6gsoz5m$pLl*zm zD#>4}@h++MA&2&VCZ1>6sJ!G!|NL@(GTzfF*Hm8T^8&w~4XVB;d3|L3y*|71Avv6f zki+#2`3u$lywA=@`d?7>Z&dxV%4hxh?ES;}`E1Xx_4_CGFxKNa-(U7;vP+gl8&w`v zc}(STl{fh;zHYqDDsNHwd6l>N9M-c<<*AAHr)-bu3+L5&)<;Y@pR)f}R&qF>q5f^W z|5i5NXD+K8&Wr0W_3OSK@?R>Smwiq$1^2v^`D%B@_bWSpEv(1+*GC5A<;%T4y6c;- znC1=hSIWKq{wC`+*~a?Ot;y?|$ZkBznRq;tE%cVBrrY;B8Q=B4P1WakKUXglb8}Tb zka!=+7K?@7{P*AOzu9a|kNr)u?$#sqD}Fxr{VJLARh55LIqkE%KGhyG#joGx@nLhq zuczDYr`pqVQsq-BpH}(%*w^*{LFFs)^>p>CDsM~rj}H&uKUT*>-E@n6{<{9N=qRkJg zT#TRJCf6Jp9##2$|Ni9GC-u)|Tzf?A^|$Tci=VGIWV??csqc@U$F3f7sDCZLbYPtB8vg(Q diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAD b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IAD deleted file mode 100755 index 09e28dae24d98bb28b38f06a100fa3e957bcdb2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1328 zcmc(fziU%b6vxj?s&r6DAsqyfjE+GN9P>CmvWxI~{8+%#}kAisXr@fsYX}L(~s)z|gI*}9YhO|@N3FIc-CA4Cr`ILTz zl93^_ew?LrK0JXbPSqLS&p(Rk(V zWsqCv&>pxw2cgU26zSn>yk}FHYdq%2H_AS^eHx8vk;`=CCiS>F%>lRr2ci4q-VNt5 zlWqGP@}0vya6KB0k~=T!Dr(L=XZ8!_6x=C|#(Os(IH@*fTg)!mp#Vp-mtp@Jb#=;h ztGDGLllDC_;P|1r=nm9XHF?rx`U52gF6TKENWcE7No$_SE+r2x@3~(=zg|qOTqhy# zCpJ<@~ diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMB b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMB deleted file mode 100755 index ae098b3b1e62d3c81c06d0a1e2ad95b0d1d48e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI#$8#H10LSqy?y-}Y&;q0vcc(Z`vr}YAmX*j6;|L}L%q+qadmt_u2mc8i=1@6psS$fr?+Yqn3(av7@nyU$vuR#jnL9-)pM)q#Yfp z_*6U!yk{%^Ht9&bq|k|W>2-@`w^uRG_H98E=Uz;D8D!EeJq241~AICDJtT>dBb z^~4R9me1TTV{;TCu?yaZkfe_>md zR-MV?^Tm4S`#W>N{XJ=X zr=2gYr^ZFh-(}|;?Y)_|1Kp{B3aEezsDKKnfC{L93aEezsDKKnfC{L93aEezsDKKn zfC{L93aEezsDKKnfC{L93aEezsDKKnfC{L93aEezsDKKnfC{L93aEezsDKKnfC{L9 z3aEezsDKKnfC{L93aEezsDKKnfC{L93aEezsDKKnfC{L93aEezsDKKnfC{L93aEez LsDKLmuLA!8I0MFg diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMD b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.IMD deleted file mode 100755 index 89d25dd212a691021743c7dd910da3306e405527..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 608 zcmbOv!oc9jV8qP8$S|Nl0BFAp(||ewY&koS1Yr#z{sMGUhD8A5j{8r*p|g^Kfeow( zNI3e0#)H@mAcEl#ipy=88F;|LK*G&81gvf%NI(FnP5>suz>vhizzgGLrx)jd*o`1U z0jN#^#DD-U1_rqKFm+2nQU*YE22e#n>L??FAdCl7HvuHz095AylVM;uk40SrNIC$h vE&!qK7bC*I0lp?+e|!Q-CjiwYAk=|aFPIq^Sb#Jr%o>1U_F=|7aF_uA274wy diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PFI b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PFI deleted file mode 100755 index 4e77fed04a1dcff181895cd52a15007659bf56ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72 ucmWN^2@ZfD00Y4yD0t)lKkFo&Y?>s6g-T;(qcf7Z>%qxow?4c~|I;55^Z>#D diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PO b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PO deleted file mode 100755 index 30a745ff6478e093e891a8e5616a4cd264cb82f7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 776 zcmXpMXJBw-FkJ!;l*V|w2m8bad!jpKK==!o7#K1J#OA?cX~fzG jjO4n83#gF=s#)OJL&gQX4;f*Gr2xej0L{Lj`hXDt8kIIx diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PR b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PR deleted file mode 100755 index 7a4ae3e421b121146f3de4c4f2d70f0b5b84b98e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6128 zcmeI$KWNlY90%}Ut=4~4s}`Y9>|hbZ-f^ba>*-cGwK$4{!h*z0_4}NLx4cGAL_xIjQkBkv5kT!gP zh*YijdcE=xZvKydLf|L<-a=e$x2!;VBD9>Y?wF!(XrduKM>d7++vRYsAhf~>tx(kF z7lh$@maRKsu9Dm=Rd@797a;A>Ng^Y#r?Q&`uw z;pf~MQBi#!5V#Dv@g**HJBo0Huu?60KF%9%QwP6W(={2RrcjbTt-x&>rMA+~lhMBV zC{>Lp8*Y42+hB?FX2DGDr#n#hGoLrxZf7KKH{tdWhmf6cd%H+=F$d#-jo|} z-jY6j1EVKE+J$;|Fw#=@X@lRbWfy~$mh>6%;yxWg)>eUpBQO0JPt)qp@w<7JV=lFq zm!-$nuCd!B+|J<8I|`oFD@4a>j83bUhm?^iH?DS#-R{6>9Y%XlUne500mrut?5BQR z_oQJ<{`b=daGSvzw-;p34ig=sae5K){c+{bTi=ZUQ<3+Pi93)nEP3jV`7AbZccJrNqyl{_uxCeEkhT{y+Rb zQGq|fd|z*;Lv2z$Wk^~L1{MpU!slTB^CxGIIXPqQJT!1}Ks=nCSDk+SC%*W}PigxD zX`f8VW}{>~ORc4}ow_7d@hp-WM7>R`)D&(QFqsI^P)X8poj$vLDqr~gfqqu2r}tNO zs!u`kRj5^|Q>YhcG-LEZ=rW>Cpt(sTNn1j$Cv}cDg0^EuWNxIQd8NT8pEMALA`aJkkoeuqf2W< zs-VznN|$CnYE1&f0e!6rAls?xsDuIu8Odt4jgP1yvl0w2FT#YvSlaBQy{mOyrxqIZ z0Szv<(I`G$sOpMho-#Da;4(3*>-acH(K<}XOtqx7S}TOE(*AE8gJV*qT7gullI9>? z@^HYM)~|pk$tt9MhyXA#uXCIqCo)<09LnY z0Z`amBo5bOfF!9)%3>NzQ#zzDycp6}O;wF??G-H-sYj@zG|n+!dFf`;Tz0I^le^v9 z(RG*+tW;)eXgrsja`CILKfm&Wn@!hFjwug8RgbUewQEkE`&0WzfBo#q)nC$$7*H}u z93pb&W}ZgBgRZWcw3$w*U0))Lk3G!?=R|06Ulp=%#ekUXYtJY`ku$3TPgv*YII5o{Vtb0aCNX zxnirSHs-5fx%;*jkQs3F0n0OjiXpFnCM-x?H0d;R;h=g3c+Lb4t=mg~grictZeTP> zuS=rW?GuftNjgbb2FMAY-6UugA5R<|xLqq`Bt(Rrqps`?m=mxOg=7d+q4NwF3&Rnz zLJ-kr#RZbF7Vxcs&ea(h$x=S$l*JJ;PZkmSO=p}}F<%ne+1|i;0iL(H&wm|^C3ZzM zGAR`MTG0fQ>6&+-@TXKIsF9i%PgznxKH z^VPnW*OA<3U_{>o)sSnf=e|lkGML+d_E^qzRwSX2Q=zXXV@0~6`_3w%*dKmaRE2|n zw4?{FIeM>Aj+Tmt)4@Sty@MVJ{+wcOI46-_s4?CqWg z5|-S!-7{&_68k){5yXOf+?l)t*bfVUn{>RU zMn`|q8TXcnzLbSARvPdkm7X=M-kt?ykdL{`aqRODp0ka8UO@)m7s3^e-RodBV0}1SfMwPo zisYqNtuQ*mZXOiVSm4`rywL$&jM-v#=1T5ouK7eWzjVrFyQmzqip7A_Gy^iFt&kXF z-sf@2@5~%1?kMJ_@XC77zCXl#5_6b(nvi97=`@hIIV;S*&(e5yQ_3(+%&462I>vEP zh}nIfn)9GjmQ2Y7lrG=}Yi^%ss(1**rBrRpvNJ;x)3f)#{|tAb{R5VzF;e|pmtMic zfK`c`L}=P_?HNf_h!Z793G=QxqjA6F)vLkh2q9v~L=gG3Umz5)C}m2WHg6X-(|OGr zb4x}SnGU@1K7S}I0Ga~G%u~+$yk))?`AqM+OL)D^;tV1)dXJu*lxN>pLtj{na9(+z zG6f@;y-ujiw)YUvs`s?@*aBpd>H_&yELkG-vGuYk)w3TQS(2*8KK~IojO(ab&;9(* z3LXJ%kHE*oMIE; zpv9xGu;UB?hT^jjbRqXj=7KZxvT5r5gpH;$Z@u8Y5W6p}P+F*~sL1_H$itqK7UU-j zct0|0LFwmx+LX0qOen{oxI|~_XhdOW2Uy|s-{lp?NH#$S`F&zoSaOAGSx%Gu?Fxeh zqM5a8%a4_8j9}9HS+=T>ne|E!gv{jgK(_Z%Ub=pimZh5RMd$Lj=`BmqmPzr&jeoR8 ze>C$)W4&x*AB}hS!sqt?1K53r8Wu*aqlvUd84bFW8ZLzKg&CgPUpwISY*Vr)hr1AaV&C$mbYF3Wk?X=->sUkd5IFQ_rDn_Emd8a#F^)k@M|`5V739 zi?k?uFS9i&sZF%{gq>^ZCGhzI3J`A%t%o2|puc@&3Am~VIk{R%WatwvjO?{1fz-K< zBOc7^O8K1@!SaVVz}VzVi2mm6m`uQYz@E!jpL!4rRM^dwXM9wJR&EzN51|a2<|}r8 zU=U-Cmf7=ueols}@GY2X+x?7|Qf#{9Vi0HhFYZFtPlzkeH;Okb_}spV=k|lQxv*iY zDdAraUZ6umN>MC6w|7`#9>SvHW<3kvKMz*gvjcO<9@68h3<>`@H%)P1pq=Y)BY0BI znKt=Y@nt&^iJ3KZJnp=_w$1*rSbqY$l2<^ox$7> zH7x`ZUEk6{6i$2IsFDM($4Z{96jnyUO<_h~dEAZ@%SaY^GRa zC8gzti*j48eU(JBFjsz1?H9w|Dxwq{uiG`??8P~;alcS}BD6S8^{ z-pxwz?_V(OKE}n{p80bVOf{7{BtlrjYmeu6`U##nr&f{Fd=*bvuBG*pi=D@gVBFon z6U4h;!pkWadpH29Pp1{t{nOWNGrfBITj{;^$8W=4+N!PhB>~QH`bF)#JNz=UwsaJk z8ABUNDd;=Lye^P83ckevAxsUV;2^PQSManH`Fe@E8;wA_PCIzt>j0jPs0?+5MUueq zcF#VvoAwn>QCbmy-3Qkroty)$TE@TRi*U5q(1i2r?mEOCf=or3?zGpnHH12bGP0H9 zUA&!w^FdP|?WIP<6kLUqx;E_0TBoG9lL+!|1q4oogj(^zaD2RQ4oNGQl9E@v#mRIv zb$1XDZ}S+0YkH7i;tC39{$^way19TOiWEbw`C1d+Pq1{zZMR=^$0_dB@-V z=jo_BMq#juQu-#{ql~QID!t!4jz9(?Pi z_k2gTt*X}3;a|92U6aNlKc>f#jgE5Ga1U=;f~N>c88B@Ol@jEZ0Ny}s>Y2GxMZpQ1 z5t#el!V>;eI^I4`H|y@jn@1P*$J%vUf9~-Qzo9+-g{C#bn)veD4sUN=+rXQl8@~dp zjT{6~6%KJq!J+SCb(feFqDL1*7oky+&OJ`(sd>G^KY%5 zq06I{Yi(!pE0~?v()wSELDtCAy&@9=$CHnhpq$Ibjv!<2Z6v}spEIL>jSu5Gca_u0CQGN4@AEi4;q3E(P;1Wbo^~8xi)bB2&HH(5wYHnmr5D1j z?VdiaP!M{b0KcDqS@JHvrCzc|j$H>A4m=1@4nRMG9&z?;W3!CG&?Q_z^OHDP-(zvk zb}Y{k7NucL5|0uor*z>I8^ym%d_S*UdV2&A`c^>$7zYRrT4M}z+n$$^hWsgH7i~4p zjQG(=PXjOc^~Zr5i?c`OGO{datr;tNBF-q6LVaQeHg6wsy6wZbCWo(!X2GSou|jyU zf*P_eLiB6&6=3N287&qH@h{a`fOA@(DA*Z#$2?C$m(w9dh~6>@>oH(&8k4|bdM}WX z0!w%wCcVYvN*-LLe7;^rp+}$0OPv=xS#LkRPwcl ze!`?+5lCj1o}{t47etXT;`k#CY-|AC8O(g-O}d8OufPXMod2!`siR%)VS`{0T;<_1(BYX^>03UQAqDP)OL~9fj|n}&d6*8XKOh;qz@75UcPL(u=CQF>|KK%G<4_YC317&5n6s6+`&nql6Wb3 zJq+j*7TmAD8v_d%?Glz*Gu>XMA?|$?6<+-j%-f++A?^*VBGyn6rO+WejQf6YoURsx z$@+b#8LP~Z^Aanw`-B*}-&W{XT!V%3e7s`do{`NRY%aFzi?==@p^&Gf{H@k@`Y8RC z^=V@_Fu?5^9mF3Nxv%_KUdaXwwK1o8jZPCC*VnJ#B;9~OLQ7$(kxKCpk}OaAp%<+V zgbe6_)p3^#2CL@48=+Yk_IV3YgH-cEs6^r#x?i$*?vx#fr7!Hi_!JWDCuG)jPd9iE z4}XM+ef~J}td}iC#>Xn=mG!IkD@oTHU1~#}K{!HbJ%W0;a4qBEbf5ADtV?IO8TKau zNTK0ffrGG>E}i?f+pIWEo~MS!oZz|(7(9b6Oandh4MN}oh z^+${Ot#80?)&B;v2)Rfm0megz%Y=tvQw1bmvIB|-n@_+$hU%rPfC0K%k){%5i3RQ0 zFS!Vdzrk?C-HD^#WL00(eW;YovPuMT@!+*>SZF@x^ti_7_LG6RadDA7l@ts4;Js%t zF^lXbtmVYK`9fWeY)&v7o{&i|9!k=)u0U+DjQjlIqNqc{i!Ezi>~I;^uukv0K+rL-zN2sW{CH1ass;YfD|n_QJjNGt}y_w%1xY4ODJ-ury2pS$Vr+b^v4V*j&T zH}#U1eSW5LGGOD?-gkpLof^gX9A1T-adCNb#;HNE>nE@j+ z=k%A=;aZ0XKC^3?hOT`NIIj<8q4#XFl82&ucQe-XKFEf3hdKjDug@-jKY$bx!zX4Z zv`O9zhFJH~{4vSxD!)E7C~#*SgBqwuojUjVm+^I?zrK^Bl?2AYt$YJdCMw<4n!Y5S zppoSbkpUvraCSXi;x}iWPPguEJ@LWs?xZ*Ez+yUM zRbU!uKX=1G!>#qzD-yg~mrU@@{V~RZ)xC}ew~uKP{WmXgIo-lN&p?ggE9l*3Q!7ml zxSz+E17|yw*qn(UVSytT8NFEn z3(Lcc5h4)6#PNziU4IffgvJtARKBTmRI57*JzTTm>uSOYYktHnU2j_39;NH4`mjsT zH2d&-fv1q@0K&%Dpc6s6Pqe@;UQ1|%l&c#tVH2S2giSyhla!HTlq|zMsIz2NfPvI$ zFLN*03rmo=l>)2e5I2he;fo94Sw)J_>|WNd|I2^yJMX-S-^mG9ZZ-Gr$nh7_$@6z# z{Qkjf)#LcNl`KZ5j&k?C8oI8oj~jhv>*60a+tqHPytt@3-@pt59wLRq!JE4_(#mF5 z6K*0M98I5Vx8Hi2p4eJ%)}`L-ZhQ*rT#l!-b1gQ)JNh03752XMTKb{zM5&XP~33~!Qz zo}~tw1_JMY4Em;^PVu3rpIBsp6a=gQEeM=Y!VYlgZ8T+!qc`S?_F2*i7JUMx|BV_E8@32km`=E#bfs@?le;OEP`$`x*@xB}(70puUpLX>c zhLAWn@_zmd(^m`>R3zV|m$!bIVqoT5)x8#2L+}@78JX@NMD#42gW z=GkBZ@?0zvhtgbo4o=B`B-FsO&*)+bZKRb^<7?0;G(<9ylHvP&;qGFuuM}*6Kerc0 zmo$ESrO_f9=~>_lQXeTXDS(&6$DmG+nrx3li_B0Ti5H-ndC+aVA~IF75y`WU2ghMQ z@Z(uzRI{(WtBp)&QOFmLwN4+-1!@fW+l-c~J1Y0{mXAN|vHhA34X9=R`N4iv#I4Z? zk)b@s<)(RcP&5ZR!^z{Tr02)6*^~Ey4EOUkXy>de$wvSl8DVUIAzQ)y{Qk%9DMSldFn3XUAXOYxWRe8=fmc z5H#3o3NW4|{6OS#fcPF@3*_Vac{nXf{rx-`huh=|8v^!uG+0;7^80z}l`H4TIgWMl zNE{O&cPSYQ>k{V=(@lQBI9sX?I=u>NShUd(3S`ECIucVu4Q)8~siiosR@{+-wDCSq z`HvSSqkQ;K)3FbJh7t#FCfu@pesD0xY)k-O6qNh?OAx$qM)yjR%VOgWRgBFdsMWdD zj74Oa$Nlb${vICQOzzBv)#a)So7s9~rE;uM>?^^tfPGWfx8&~&ep<1qTmBy2ALD_g z;DV3=b3rBaJ+<+g40hjcO;>E;k7wmJnK49Sv(CnGP$iFB}+TmE*nub;zTQ;Gnf@@u19c! zf0Gm_+Vb2!?_kyo9BGa)VVhl3uL-P$Jiklwur(f-U`TyQ;fx`0!uI0DQ!xVvAZ+>} zlfZ~3k5$EaT)H!m)6QI(kruLC+|I-(V)VS2JU^-r5SZM!G{Y9+{`Ghd;+S+w9gJ5q z0I_F(YyYvEH*t*3Xt>&_xzx1rYu%fFx3*_L(Adad9)v-6rX%jJKuR zHLcQJn;+9I{7mZt#w_S8!)bYK0ETP1 zXSV=!hR4Abu!3COfnDT+i5NQO#7XB@rAeuO@X zu+V`miy__eqx#*gE`4lo&1CGwY zyoD>ijk%rdcCg1ScPmD%UAC9-W7zNeIg``>^2|?vqrpD^;?Hh9mpLd$%o z39P|~w(L2o44QkPus^t>q)|T08j&sY>mBqWrB0RD;nqC9R)#aUWH<*H0fkb8ip-!?b$Mc~_Ww4p9gL=#R@K8{Ar&(8T zG9@~oGjQ=w&9qLY@N8fP*uK#lc5f;Z#9N%naIP~9AeK>ARd=iQCfrctHd`cvi(l<< zS_E06!5Kp+@+aa{RfM;2ApEH01lP}hehT3>HBy!N1lTpZ(Dnrmyyzkx&&B_+2FeZv3>S;W03tPIQ# z0Y7V>k`nWW&2M~L4Wn!4Cwui)`lGaW@(0I_Tw-y_dM4A?)uf?1^!m{^fgRI zbs^2lm(nUOHLE+RTD`#`8>^27rU6()QE4(bUZ?hOh#Lq%UIU7wYr_@5FwBI;2@fwa z!z~5?Tb#T!RVPPEy8u6updViF=W$@mN!|q%!FFBG#qh(UZZDm3(i9D5sj1wCX;sOf za0jQ4>N*ZAXxW?e9T?pyj*pvl4GUKE&(V9I&oI`EHeeKIU{O~(hjSn=!=5JW5ST|T$B$I1Lq{T zXv4pTmGAR0ox!Kt5kAEyY20)1j8PO6->hu-aKIF5`sE!J3Ah%GIr7mYB@c}G)F~Le zic>*nU2foWpmQA9y!JCN5lBW-T*`RdTjVbWv2^x_E0~OG=6*f~Fg8+u-~JoPR`b%*OiSP4)B3(rR;G*6_BS;Ycj~e3|k_zV( z@F0erguX8fptwdG0Mpe_XAZ1Xqa>S^qRRxWloA3+2G%n&BGJbJ&OA>g zN2xOpoms|XpWon2@QV}kgBe#D$d%W@J_6U3NmR+^<4$Sr@N9Is)d{tXK-QDQU5^<6 z?nJ*QPL(J@+Xfs9GVtL3mY4{B-(IoLtA9UVD!4FJjQ;@v zjtf|7`fI4dyRskFYM+b^21J#lV9jA^UG&qH*Pww}wp9Pt6yMJ)^c@D@B%!$s#zQVf zYIEAQeBJlD+G9jOHL)`L(GBv58m$d%8aYJ5FqF*5-N}fY+2>0X@56JpE)rbukIY9X z(~ML{Ob(d){0J=L;_2Z%yr8l95Q#82BYC}}mVPo7GT@&f7G+@WufGVRFO;uLMv(W{ z3e~bSXQ@~ZS=BVh~%E%NN=2iF16qw)Z~ zkSrVcV=PyJ3OeRLVjS6yj|86#jxSZ|4DBS-vYv6Piqk9pGb%nj%sB5INslcEee*OStzH#56#f@F@QA%e`+#iWh&NC zv^LVvjQ6f(Bm{agA{X!Tz2_NAH_SV-FS$yKSuS;)Y=5KcwYO5W#j zEHBP5`+&N3+~r^Ghait=Qi?~^am=+(O+ zr>PWF775Vr)M)XoIPWE~&rbm&1AhQ89sukCbjv=Ue87hS(>^i^hK#*z!#yYf0ai|6YnS_E*$%MzbgTP(6pEGEkl=eh>gK96@=XN72a_HV*}h*XTpJdJv<2 zzGjRbqHr@Ft{`WEI_clfzhP$o)8Zsgiu9Ib;O%a-^+#`f=j@-Ix@LJo%kN2sDS|F; z+hZ}d)oYl?KmT-n_xtsiU%ysA)rn!1X21T`HHVIm8f{eY@C+j~|E;xnnuC`E}Otw!M9|1Qq-NL-#Xbo zKC0?7xW)JLUAwY%x>d;`ejP*bz3pwY_0%%|vB6yFC3UUa6fk5Lrg{kf%rMB+8s%+mN3094N-2V~x4 z8N`>!6O9zLl(0P|eY@P}&gN6h%55`^HBpwTLQrxWS}Dtz#}w?vaPc<~U904gaW z)F5$FBjE8DQ+)@LLpX*L*gD^>)%CIeH))m6XH(N^tCifjdkV=xeH(ushg&ziEn4Fw zgt6;B)>74eRq*8WGOa4i_}pG`4z>!#*G;T-_<=DJa738-rq(-PmS^>X=k_XQV0B6G z4nSIA4Vev}SU!d4_Wli;FBQEM@Ri@sGieeDx0?fWnGl#d2srSkN(wgl%ZNLe@>(R_ zVVq=a0x(P5=gC%l&d)A3FQ?fB*fBKX-uN z4R$UBOk43Gn73@6Yrg#JU-`-JS1-Ng@t?fCaqee}k!C1@QFFHGpu1$B!JWVQxn||J zzjpEYw0-(U3})|6{VYAimjI_ZYcLF>Zouc5kR?Fa00lSlV}kzNejf~9z*YTH-MrG) zUwf&2-*&Q_KVR=95naP*^_{1ke2&gc=@{kewn*eZCUtW!K0*;pz4MsE09GM%ts3)3d6>KqE|l@nfNmV}l4z1uOx#$a9eRqW0K5b?GUJ zt5|Xu0{p-Q=CLo40)%t{1Ri)l-*8ETMBExofZ>B<@eW?cAW31PSq3FKjD<}hKoWMe zFk8c~newcFe?p7;IW~MfjnGkzfb^CB&;W4GaRd$bd8`MhLPe-v;~y9xFG2CB(g@`u z%PwM25aYPbEOcg2Rd9Tr=z9L0oEO3yythduHCDs!z?Fot0Tr({u)z`cb1LFHil!2L z)e95f7SIRmsP_jcdJ-_F>oHt{Xwnb3Ln?o7kzn}vu7md}a~QG#+iY+}!7c!DMRHLZ z_QBqxSKS2z3Yattc9xP*d@LOh9RV+w)xeNoHe3Y^d5O|o3tqIGI{2=A9c4kS2!((6 z&KD*buqGAJD#02R7Lx7&)I$oud7XZ?|A)Mi!Y`0RH^9)fXrxOP$_n$gJhw-1Iyy}q zzKkUpK0aGJzBNY_L@%Kr2Jp~s>SIr&d9_i5%Tr9L_&;_4Yz93j1yY+c)_S&y5ND(K z1W;^s*X|)b&teB{h0w#@as%HnCa4TyaMcmNZ%;>%(}Sf~8=P&++RKAwI7>XTaOvg_ z1}{|R5s#y&N?(K;PY(^A+jqE{L>}p_DrkXX?CN(=f4t&}rpDbHggEgkzgXg^lc|v)!an>Og6$=oeC*s^B#x-96%GMAPRewY z$jK=5hDf?jkK(zKq?yVlr-$~ z1~ylA?O8Bc7HR@ppw=fG%QrV(sELH`9b(uLi3S0FNWmp|Am?;QAcG{aD&rNG;tj}- hoDq|`A422oo#T$8I3=Bf!?C8vxjq8&KHr4+{{kry?^^%> diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PS b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.PS deleted file mode 100755 index 0d0fa1d5d8cf6795befa17f7ce540b66ee2d4f39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 186272 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 AH2?qr diff --git a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.SearchResults b/drivers/video/msm/gpu/KGSL_SI/Untitled Project.SearchResults deleted file mode 100755 index 71943fcd..00000000 --- a/drivers/video/msm/gpu/KGSL_SI/Untitled Project.SearchResults +++ /dev/null @@ -1,12 +0,0 @@ ----- CONFIG_MSM_KGSL_MMU Matches (11 in 6 files) ---- -kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_device.h (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_log.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_log.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_mmu.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifndef CONFIG_MSM_KGSL_MMU -kgsl_mmu.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_mmu.h (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_yamato.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU -kgsl_yamato.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU diff --git a/drivers/video/msm/gpu/kgsl/Makefile b/drivers/video/msm/gpu/kgsl/Makefile deleted file mode 100644 index 0290b50c..00000000 --- a/drivers/video/msm/gpu/kgsl/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -msm_kgsl-objs = \ - kgsl_drawctxt.o \ - kgsl_cmdstream.o \ - kgsl.o \ - kgsl_log.o \ - kgsl_mmu.o \ - kgsl_ringbuffer.o \ - kgsl_sharedmem.o \ - kgsl_yamato.o - -obj-$(CONFIG_GPU_MSM_KGSL) += msm_kgsl.o diff --git a/drivers/video/msm/gpu/kgsl/kgsl.c b/drivers/video/msm/gpu/kgsl/kgsl.c deleted file mode 100644 index 2d296514..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl.c +++ /dev/null @@ -1,1228 +0,0 @@ -/* -* Copyright (c) 2008-2009 QUALCOMM USA, INC. -* -* All source code in this file is licensed under the following license -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* version 2 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, you can find it at http://www.fsf.org -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kgsl.h" -#include "kgsl_drawctxt.h" -#include "kgsl_ringbuffer.h" -#include "kgsl_cmdstream.h" -#include "kgsl_log.h" - -struct kgsl_file_private { - struct list_head list; - struct list_head mem_list; - uint32_t ctxt_id_mask; - struct kgsl_pagetable *pagetable; - unsigned long vmalloc_size; -}; - -static void kgsl_put_phys_file(struct file *file); - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -static long flush_l1_cache_range(unsigned long addr, int size) -{ - struct page *page; - pte_t *pte_ptr; - unsigned long end; - - for (end = addr; end < (addr + size); end += KGSL_PAGESIZE) { - pte_ptr = kgsl_get_pte_from_vaddr(end); - if (!pte_ptr) - return -EINVAL; - - page = pte_page(pte_val(*pte_ptr)); - if (!page) { - KGSL_DRV_ERR("could not find page for pte\n"); - pte_unmap(pte_ptr); - return -EINVAL; - } - - pte_unmap(pte_ptr); - flush_dcache_page(page); - } - - return 0; -} - -static long flush_l1_cache_all(struct kgsl_file_private *private) -{ - int result = 0; - struct kgsl_mem_entry *entry = NULL; - - kgsl_yamato_runpending(&kgsl_driver.yamato_device); - list_for_each_entry(entry, &private->mem_list, list) { - if (KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH & entry->memdesc.priv) { - result = - flush_l1_cache_range((unsigned long)entry-> - memdesc.hostptr, - entry->memdesc.size); - if (result) - goto done; - } - } -done: - return result; -} -#else -static inline long flush_l1_cache_range(unsigned long addr, int size) -{ return 0; } - -static inline long flush_l1_cache_all(struct kgsl_file_private *private) -{ return 0; } -#endif - -/*this is used for logging, so that we can call the dev_printk - functions without export struct kgsl_driver everywhere*/ -struct device *kgsl_driver_getdevnode(void) -{ - BUG_ON(kgsl_driver.pdev == NULL); - return &kgsl_driver.pdev->dev; -} - -/* the hw and clk enable/disable funcs must be either called from softirq or - * with mutex held */ -static void kgsl_clk_enable(void) -{ - clk_set_rate(kgsl_driver.ebi1_clk, 128000000); - clk_enable(kgsl_driver.imem_clk); - if (kgsl_driver.grp_pclk) - clk_enable(kgsl_driver.grp_pclk); - clk_enable(kgsl_driver.grp_clk); -} - -static void kgsl_clk_disable(void) -{ - clk_disable(kgsl_driver.grp_clk); - if (kgsl_driver.grp_pclk) - clk_disable(kgsl_driver.grp_pclk); - clk_disable(kgsl_driver.imem_clk); - clk_set_rate(kgsl_driver.ebi1_clk, 0); -} - -static void kgsl_hw_disable(void) -{ - kgsl_driver.active = false; - disable_irq(kgsl_driver.interrupt_num); - kgsl_clk_disable(); - pr_debug("kgsl: hw disabled\n"); - wake_unlock(&kgsl_driver.wake_lock); -} - -static void kgsl_hw_enable(void) -{ - wake_lock(&kgsl_driver.wake_lock); - kgsl_clk_enable(); - enable_irq(kgsl_driver.interrupt_num); - kgsl_driver.active = true; - pr_debug("kgsl: hw enabled\n"); -} - -static void kgsl_hw_get_locked(void) -{ - /* active_cnt is protected by driver mutex */ - if (kgsl_driver.active_cnt++ == 0) { - if (kgsl_driver.active) { - del_timer_sync(&kgsl_driver.standby_timer); - barrier(); - } - if (!kgsl_driver.active) - kgsl_hw_enable(); - } -} - -static void kgsl_hw_put_locked(bool start_timer) -{ - if ((--kgsl_driver.active_cnt == 0) && start_timer) { - mod_timer(&kgsl_driver.standby_timer, - jiffies + msecs_to_jiffies(20)); - } -} - -static void kgsl_do_standby_timer(unsigned long data) -{ - if (kgsl_yamato_is_idle(&kgsl_driver.yamato_device)) - kgsl_hw_disable(); - else - mod_timer(&kgsl_driver.standby_timer, - jiffies + msecs_to_jiffies(10)); -} - -/* file operations */ -static int kgsl_first_open_locked(void) -{ - int result = 0; - - BUG_ON(kgsl_driver.active); - BUG_ON(kgsl_driver.active_cnt); - - kgsl_clk_enable(); - - /* init devices */ - result = kgsl_yamato_init(&kgsl_driver.yamato_device, - &kgsl_driver.yamato_config); - if (result != 0) - goto done; - - result = kgsl_yamato_start(&kgsl_driver.yamato_device, 0); - if (result != 0) - goto done; - -done: - kgsl_clk_disable(); - return result; -} - -static int kgsl_last_release_locked(void) -{ - BUG_ON(kgsl_driver.active_cnt); - - disable_irq(kgsl_driver.interrupt_num); - - kgsl_yamato_stop(&kgsl_driver.yamato_device); - - /* close devices */ - kgsl_yamato_close(&kgsl_driver.yamato_device); - - kgsl_clk_disable(); - kgsl_driver.active = false; - wake_unlock(&kgsl_driver.wake_lock); - - return 0; -} - -static int kgsl_release(struct inode *inodep, struct file *filep) -{ - int result = 0; - unsigned int i; - struct kgsl_mem_entry *entry, *entry_tmp; - struct kgsl_file_private *private = NULL; - - mutex_lock(&kgsl_driver.mutex); - - private = filep->private_data; - BUG_ON(private == NULL); - filep->private_data = NULL; - list_del(&private->list); - - kgsl_hw_get_locked(); - - for (i = 0; i < KGSL_CONTEXT_MAX; i++) - if (private->ctxt_id_mask & (1 << i)) - kgsl_drawctxt_destroy(&kgsl_driver.yamato_device, i); - - list_for_each_entry_safe(entry, entry_tmp, &private->mem_list, list) - kgsl_remove_mem_entry(entry); - - if (private->pagetable != NULL) { - kgsl_yamato_cleanup_pt(&kgsl_driver.yamato_device, - private->pagetable); - kgsl_mmu_destroypagetableobject(private->pagetable); - private->pagetable = NULL; - } - - kfree(private); - - if (atomic_dec_return(&kgsl_driver.open_count) == 0) { - KGSL_DRV_VDBG("last_release\n"); - kgsl_hw_put_locked(false); - result = kgsl_last_release_locked(); - } else - kgsl_hw_put_locked(true); - - mutex_unlock(&kgsl_driver.mutex); - - return result; -} - -static int kgsl_open(struct inode *inodep, struct file *filep) -{ - int result = 0; - struct kgsl_file_private *private = NULL; - - KGSL_DRV_DBG("file %p pid %d\n", filep, task_pid_nr(current)); - - - if (filep->f_flags & O_EXCL) { - KGSL_DRV_ERR("O_EXCL not allowed\n"); - return -EBUSY; - } - - private = kzalloc(sizeof(*private), GFP_KERNEL); - if (private == NULL) { - KGSL_DRV_ERR("cannot allocate file private data\n"); - return -ENOMEM; - } - - mutex_lock(&kgsl_driver.mutex); - - private->ctxt_id_mask = 0; - INIT_LIST_HEAD(&private->mem_list); - - filep->private_data = private; - - list_add(&private->list, &kgsl_driver.client_list); - - if (atomic_inc_return(&kgsl_driver.open_count) == 1) { - result = kgsl_first_open_locked(); - if (result != 0) - goto done; - } - - kgsl_hw_get_locked(); - - /*NOTE: this must happen after first_open */ - private->pagetable = - kgsl_mmu_createpagetableobject(&kgsl_driver.yamato_device.mmu); - if (private->pagetable == NULL) { - result = -ENOMEM; - goto done; - } - result = kgsl_yamato_setup_pt(&kgsl_driver.yamato_device, - private->pagetable); - if (result) { - kgsl_mmu_destroypagetableobject(private->pagetable); - private->pagetable = NULL; - goto done; - } - private->vmalloc_size = 0; -done: - kgsl_hw_put_locked(true); - mutex_unlock(&kgsl_driver.mutex); - if (result != 0) - kgsl_release(inodep, filep); - return result; -} - - -/*call with driver locked */ -static struct kgsl_mem_entry * -kgsl_sharedmem_find(struct kgsl_file_private *private, unsigned int gpuaddr) -{ - struct kgsl_mem_entry *entry = NULL, *result = NULL; - - BUG_ON(private == NULL); - - list_for_each_entry(entry, &private->mem_list, list) { - if (entry->memdesc.gpuaddr == gpuaddr) { - result = entry; - break; - } - } - return result; -} - -/*call with driver locked */ -struct kgsl_mem_entry * -kgsl_sharedmem_find_region(struct kgsl_file_private *private, - unsigned int gpuaddr, - size_t size) -{ - struct kgsl_mem_entry *entry = NULL, *result = NULL; - - BUG_ON(private == NULL); - - list_for_each_entry(entry, &private->mem_list, list) { - if (gpuaddr >= entry->memdesc.gpuaddr && - ((gpuaddr + size) <= - (entry->memdesc.gpuaddr + entry->memdesc.size))) { - result = entry; - break; - } - } - - return result; -} - -/*call all ioctl sub functions with driver locked*/ - -static long kgsl_ioctl_device_getproperty(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_device_getproperty param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - result = kgsl_yamato_getproperty(&kgsl_driver.yamato_device, - param.type, - param.value, param.sizebytes); -done: - return result; -} - -static long kgsl_ioctl_device_regread(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_device_regread param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - result = kgsl_yamato_regread(&kgsl_driver.yamato_device, - param.offsetwords, ¶m.value); - if (result != 0) - goto done; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto done; - } -done: - return result; -} - - -static long kgsl_ioctl_device_waittimestamp(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_device_waittimestamp param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - /* Don't wait forever, set a max value for now */ - if (param.timeout == -1) - param.timeout = 10 * MSEC_PER_SEC; - result = kgsl_yamato_waittimestamp(&kgsl_driver.yamato_device, - param.timestamp, - param.timeout); - - kgsl_yamato_runpending(&kgsl_driver.yamato_device); -done: - return result; -} - -static long kgsl_ioctl_rb_issueibcmds(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_ringbuffer_issueibcmds param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - if (param.drawctxt_id >= KGSL_CONTEXT_MAX - || (private->ctxt_id_mask & 1 << param.drawctxt_id) == 0) { - result = -EINVAL; - KGSL_DRV_ERR("invalid drawctxt drawctxt_id %d\n", - param.drawctxt_id); - result = -EINVAL; - goto done; - } - - if (kgsl_sharedmem_find_region(private, param.ibaddr, - param.sizedwords*sizeof(uint32_t)) == NULL) { - KGSL_DRV_ERR("invalid cmd buffer ibaddr %08x sizedwords %d\n", - param.ibaddr, param.sizedwords); - result = -EINVAL; - goto done; - - } - - result = kgsl_ringbuffer_issueibcmds(&kgsl_driver.yamato_device, - param.drawctxt_id, - param.ibaddr, - param.sizedwords, - ¶m.timestamp, - param.flags); - if (result != 0) - goto done; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto done; - } -done: - return result; -} - -static long kgsl_ioctl_cmdstream_readtimestamp(struct kgsl_file_private - *private, void __user *arg) -{ - int result = 0; - struct kgsl_cmdstream_readtimestamp param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - param.timestamp = - kgsl_cmdstream_readtimestamp(&kgsl_driver.yamato_device, - param.type); - if (result != 0) - goto done; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto done; - } -done: - return result; -} - -static long kgsl_ioctl_cmdstream_freememontimestamp(struct kgsl_file_private - *private, void __user *arg) -{ - int result = 0; - struct kgsl_cmdstream_freememontimestamp param; - struct kgsl_mem_entry *entry = NULL; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - entry = kgsl_sharedmem_find(private, param.gpuaddr); - if (entry == NULL) { - KGSL_DRV_ERR("invalid gpuaddr %08x\n", param.gpuaddr); - result = -EINVAL; - goto done; - } - - if (entry->memdesc.priv & KGSL_MEMFLAGS_VMALLOC_MEM) - entry->memdesc.priv &= ~KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH; - - result = kgsl_cmdstream_freememontimestamp(&kgsl_driver.yamato_device, - entry, - param.timestamp, - param.type); - - kgsl_yamato_runpending(&kgsl_driver.yamato_device); - -done: - return result; -} - -static long kgsl_ioctl_drawctxt_create(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_drawctxt_create param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - result = kgsl_drawctxt_create(&kgsl_driver.yamato_device, - private->pagetable, - param.flags, - ¶m.drawctxt_id); - if (result != 0) - goto done; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto done; - } - - private->ctxt_id_mask |= 1 << param.drawctxt_id; - -done: - return result; -} - -static long kgsl_ioctl_drawctxt_destroy(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_drawctxt_destroy param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - if (param.drawctxt_id >= KGSL_CONTEXT_MAX - || (private->ctxt_id_mask & 1 << param.drawctxt_id) == 0) { - result = -EINVAL; - goto done; - } - - result = kgsl_drawctxt_destroy(&kgsl_driver.yamato_device, - param.drawctxt_id); - if (result == 0) - private->ctxt_id_mask &= ~(1 << param.drawctxt_id); - -done: - return result; -} - -void kgsl_remove_mem_entry(struct kgsl_mem_entry *entry) -{ - kgsl_mmu_unmap(entry->memdesc.pagetable, - entry->memdesc.gpuaddr & KGSL_PAGEMASK, - entry->memdesc.size); - if (KGSL_MEMFLAGS_VMALLOC_MEM & entry->memdesc.priv) { - vfree((void *)entry->memdesc.physaddr); - entry->priv->vmalloc_size -= entry->memdesc.size; - } else - kgsl_put_phys_file(entry->pmem_file); - list_del(&entry->list); - - if (entry->free_list.prev) - list_del(&entry->free_list); - - kfree(entry); - -} - -static long kgsl_ioctl_sharedmem_free(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_sharedmem_free param; - struct kgsl_mem_entry *entry = NULL; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - entry = kgsl_sharedmem_find(private, param.gpuaddr); - if (entry == NULL) { - KGSL_DRV_ERR("invalid gpuaddr %08x\n", param.gpuaddr); - result = -EINVAL; - goto done; - } - - kgsl_remove_mem_entry(entry); -done: - return result; -} - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -static int kgsl_ioctl_sharedmem_from_vmalloc(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0, len; - struct kgsl_sharedmem_from_vmalloc param; - struct kgsl_mem_entry *entry = NULL; - void *vmalloc_area; - struct vm_area_struct *vma; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto error; - } - - if (!param.hostptr) { - KGSL_DRV_ERR - ("Invalid host pointer of malloc passed: param.hostptr " - "%08x\n", param.hostptr); - result = -EINVAL; - goto error; - } - - vma = find_vma(current->mm, param.hostptr); - if (!vma) { - KGSL_MEM_ERR("Could not find vma for address %x\n", - param.hostptr); - result = -EINVAL; - goto error; - } - len = vma->vm_end - vma->vm_start; - if (vma->vm_pgoff || !IS_ALIGNED(len, PAGE_SIZE) - || !IS_ALIGNED(vma->vm_start, PAGE_SIZE)) { - KGSL_MEM_ERR - ("kgsl vmalloc mapping must be at offset 0 and page aligned\n"); - result = -EINVAL; - goto error; - } - if (vma->vm_start != param.hostptr) { - KGSL_MEM_ERR - ("vma start address is not equal to mmap address\n"); - result = -EINVAL; - goto error; - } - - if ((private->vmalloc_size + len) > KGSL_GRAPHICS_MEMORY_LOW_WATERMARK - && !param.force_no_low_watermark) { - result = -ENOMEM; - goto error; - } - - entry = kzalloc(sizeof(struct kgsl_mem_entry), GFP_KERNEL); - if (entry == NULL) { - result = -ENOMEM; - goto error; - } - - /* allocate memory and map it to user space */ - vmalloc_area = vmalloc_user(len); - if (!vmalloc_area) { - KGSL_MEM_ERR("vmalloc failed\n"); - result = -ENOMEM; - goto error_free_entry; - } - if (!kgsl_cache_enable) { - /* If we are going to map non-cached, make sure to flush the - * cache to ensure that previously cached data does not - * overwrite this memory */ - dmac_flush_range(vmalloc_area, vmalloc_area + len); - KGSL_MEM_INFO("Caching for memory allocation turned off\n"); - vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); - } else { - KGSL_MEM_INFO("Caching for memory allocation turned on\n"); - } - - result = remap_vmalloc_range(vma, vmalloc_area, 0); - if (result) { - KGSL_MEM_ERR("remap_vmalloc_range returned %d\n", result); - goto error_free_vmalloc; - } - - result = - kgsl_mmu_map(private->pagetable, (unsigned long)vmalloc_area, len, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, - &entry->memdesc.gpuaddr, KGSL_MEMFLAGS_ALIGN4K); - - if (result != 0) - goto error_free_vmalloc; - - entry->memdesc.pagetable = private->pagetable; - entry->memdesc.size = len; - entry->memdesc.hostptr = (void *)param.hostptr; - entry->memdesc.priv = KGSL_MEMFLAGS_VMALLOC_MEM | - KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH; - entry->memdesc.physaddr = (unsigned long)vmalloc_area; - entry->priv = private; - - param.gpuaddr = entry->memdesc.gpuaddr; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto error_unmap_entry; - } - private->vmalloc_size += len; - list_add(&entry->list, &private->mem_list); - - return 0; - -error_unmap_entry: - kgsl_mmu_unmap(private->pagetable, entry->memdesc.gpuaddr, - entry->memdesc.size); - -error_free_vmalloc: - vfree(vmalloc_area); - -error_free_entry: - kfree(entry); - -error: - return result; -} -#else -static inline int kgsl_ioctl_sharedmem_from_vmalloc( - struct kgsl_file_private *private, void __user *arg) -{ - return -ENOSYS; -} -#endif - -static int kgsl_get_phys_file(int fd, unsigned long *start, unsigned long *len, - struct file **filep) -{ - struct file *fbfile; - int put_needed; - unsigned long vstart = 0; - int ret = 0; - dev_t rdev; - struct fb_info *info; - - *filep = NULL; - if (!get_pmem_file(fd, start, &vstart, len, filep)) - return 0; - - fbfile = fget_light(fd, &put_needed); - if (fbfile == NULL) - return -1; - - rdev = fbfile->f_dentry->d_inode->i_rdev; - info = MAJOR(rdev) == FB_MAJOR ? registered_fb[MINOR(rdev)] : NULL; - if (info) { - *start = info->fix.smem_start; - *len = info->fix.smem_len; - ret = 0; - } else - ret = -1; - fput_light(fbfile, put_needed); - - return ret; -} - -static void kgsl_put_phys_file(struct file *file) -{ - KGSL_DRV_DBG("put phys file %p\n", file); - if (file) - put_pmem_file(file); -} - -static int kgsl_ioctl_sharedmem_from_pmem(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_sharedmem_from_pmem param; - struct kgsl_mem_entry *entry = NULL; - unsigned long start = 0, len = 0; - struct file *pmem_file = NULL; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto error; - } - - if (kgsl_get_phys_file(param.pmem_fd, &start, &len, &pmem_file)) { - result = -EINVAL; - goto error; - } else if (param.offset + param.len > len) { - KGSL_DRV_ERR("%s: region too large 0x%x + 0x%x >= 0x%lx\n", - __func__, param.offset, param.len, len); - result = -EINVAL; - goto error_put_pmem; - } - - KGSL_MEM_INFO("get phys file %p start 0x%lx len 0x%lx\n", - pmem_file, start, len); - KGSL_DRV_DBG("locked phys file %p\n", pmem_file); - - entry = kzalloc(sizeof(*entry), GFP_KERNEL); - if (entry == NULL) { - result = -ENOMEM; - goto error_put_pmem; - } - - entry->pmem_file = pmem_file; - - entry->memdesc.pagetable = private->pagetable; - - /* Any MMU mapped memory must have a length in multiple of PAGESIZE */ - entry->memdesc.size = ALIGN(param.len, PAGE_SIZE); - - /*we shouldn't need to write here from kernel mode */ - entry->memdesc.hostptr = NULL; - - /* ensure that MMU mappings are at page boundary */ - entry->memdesc.physaddr = start + (param.offset & KGSL_PAGEMASK); - result = kgsl_mmu_map(private->pagetable, entry->memdesc.physaddr, - entry->memdesc.size, GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, - &entry->memdesc.gpuaddr, - KGSL_MEMFLAGS_ALIGN4K | KGSL_MEMFLAGS_CONPHYS); - if (result) - goto error_free_entry; - - /* If the offset is not at 4K boundary then add the correct offset - * value to gpuaddr */ - entry->memdesc.gpuaddr += (param.offset & ~KGSL_PAGEMASK); - param.gpuaddr = entry->memdesc.gpuaddr; - - if (copy_to_user(arg, ¶m, sizeof(param))) { - result = -EFAULT; - goto error_unmap_entry; - } - list_add(&entry->list, &private->mem_list); - return result; - -error_unmap_entry: - kgsl_mmu_unmap(entry->memdesc.pagetable, - entry->memdesc.gpuaddr & KGSL_PAGEMASK, - entry->memdesc.size); -error_free_entry: - kfree(entry); - -error_put_pmem: - kgsl_put_phys_file(pmem_file); - -error: - return result; -} - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -/*This function flushes a graphics memory allocation from CPU cache - *when caching is enabled with MMU*/ -static int kgsl_ioctl_sharedmem_flush_cache(struct kgsl_file_private *private, - void __user *arg) -{ - int result = 0; - struct kgsl_mem_entry *entry; - struct kgsl_sharedmem_free param; - - if (copy_from_user(¶m, arg, sizeof(param))) { - result = -EFAULT; - goto done; - } - - entry = kgsl_sharedmem_find(private, param.gpuaddr); - if (!entry) { - KGSL_DRV_ERR("invalid gpuaddr %08x\n", param.gpuaddr); - result = -EINVAL; - goto done; - } - result = flush_l1_cache_range((unsigned long)entry->memdesc.hostptr, - entry->memdesc.size); - /* Mark memory as being flushed so we don't flush it again */ - entry->memdesc.priv &= ~KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH; -done: - return result; -} -#else -static int kgsl_ioctl_sharedmem_flush_cache(struct kgsl_file_private *private, - void __user *arg) -{ - return -ENOSYS; -} -#endif - - -static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) -{ - int result = 0; - struct kgsl_file_private *private = filep->private_data; - struct kgsl_drawctxt_set_bin_base_offset binbase; - - BUG_ON(private == NULL); - - KGSL_DRV_VDBG("filep %p cmd 0x%08x arg 0x%08lx\n", filep, cmd, arg); - - mutex_lock(&kgsl_driver.mutex); - - kgsl_hw_get_locked(); - - switch (cmd) { - - case IOCTL_KGSL_DEVICE_GETPROPERTY: - result = - kgsl_ioctl_device_getproperty(private, (void __user *)arg); - break; - - case IOCTL_KGSL_DEVICE_REGREAD: - result = kgsl_ioctl_device_regread(private, (void __user *)arg); - break; - - case IOCTL_KGSL_DEVICE_WAITTIMESTAMP: - result = kgsl_ioctl_device_waittimestamp(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_RINGBUFFER_ISSUEIBCMDS: - if (kgsl_cache_enable) - flush_l1_cache_all(private); - result = kgsl_ioctl_rb_issueibcmds(private, (void __user *)arg); - break; - - case IOCTL_KGSL_CMDSTREAM_READTIMESTAMP: - result = - kgsl_ioctl_cmdstream_readtimestamp(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_CMDSTREAM_FREEMEMONTIMESTAMP: - result = - kgsl_ioctl_cmdstream_freememontimestamp(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_DRAWCTXT_CREATE: - result = kgsl_ioctl_drawctxt_create(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_DRAWCTXT_DESTROY: - result = - kgsl_ioctl_drawctxt_destroy(private, (void __user *)arg); - break; - - case IOCTL_KGSL_SHAREDMEM_FREE: - result = kgsl_ioctl_sharedmem_free(private, (void __user *)arg); - break; - - case IOCTL_KGSL_SHAREDMEM_FROM_VMALLOC: - kgsl_yamato_runpending(&kgsl_driver.yamato_device); - result = kgsl_ioctl_sharedmem_from_vmalloc(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_SHAREDMEM_FLUSH_CACHE: - if (kgsl_cache_enable) - result = kgsl_ioctl_sharedmem_flush_cache(private, - (void __user *)arg); - break; - case IOCTL_KGSL_SHAREDMEM_FROM_PMEM: - kgsl_yamato_runpending(&kgsl_driver.yamato_device); - result = kgsl_ioctl_sharedmem_from_pmem(private, - (void __user *)arg); - break; - - case IOCTL_KGSL_DRAWCTXT_SET_BIN_BASE_OFFSET: - if (copy_from_user(&binbase, (void __user *)arg, - sizeof(binbase))) { - result = -EFAULT; - break; - } - - if (private->ctxt_id_mask & (1 << binbase.drawctxt_id)) { - result = kgsl_drawctxt_set_bin_base_offset( - &kgsl_driver.yamato_device, - binbase.drawctxt_id, - binbase.offset); - } else { - result = -EINVAL; - KGSL_DRV_ERR("invalid drawctxt drawctxt_id %d\n", - binbase.drawctxt_id); - } - break; - - default: - KGSL_DRV_ERR("invalid ioctl code %08x\n", cmd); - result = -EINVAL; - break; - } - - kgsl_hw_put_locked(true); - mutex_unlock(&kgsl_driver.mutex); - KGSL_DRV_VDBG("result %d\n", result); - return result; -} - -static struct file_operations kgsl_fops = { - .owner = THIS_MODULE, - .release = kgsl_release, - .open = kgsl_open, - .unlocked_ioctl = kgsl_ioctl, -}; - - -struct kgsl_driver kgsl_driver = { - .misc = { - .name = DRIVER_NAME, - .minor = MISC_DYNAMIC_MINOR, - .fops = &kgsl_fops, - }, - .open_count = ATOMIC_INIT(0), - .mutex = __MUTEX_INITIALIZER(kgsl_driver.mutex), -}; - -static void kgsl_driver_cleanup(void) -{ - - wake_lock_destroy(&kgsl_driver.wake_lock); - - if (kgsl_driver.interrupt_num > 0) { - if (kgsl_driver.have_irq) { - free_irq(kgsl_driver.interrupt_num, NULL); - kgsl_driver.have_irq = 0; - } - kgsl_driver.interrupt_num = 0; - } - - /* shutdown memory apertures */ - kgsl_sharedmem_close(&kgsl_driver.shmem); - - if (kgsl_driver.grp_clk) { - clk_put(kgsl_driver.grp_clk); - kgsl_driver.grp_clk = NULL; - } - - if (kgsl_driver.imem_clk != NULL) { - clk_put(kgsl_driver.imem_clk); - kgsl_driver.imem_clk = NULL; - } - - if (kgsl_driver.ebi1_clk != NULL) { - clk_put(kgsl_driver.ebi1_clk); - kgsl_driver.ebi1_clk = NULL; - } - - kgsl_driver.pdev = NULL; - -} - - -static int __devinit kgsl_platform_probe(struct platform_device *pdev) -{ - int result = 0; - struct clk *clk; - struct resource *res = NULL; - - kgsl_debug_init(); - - INIT_LIST_HEAD(&kgsl_driver.client_list); - - /*acquire clocks */ - BUG_ON(kgsl_driver.grp_clk != NULL); - BUG_ON(kgsl_driver.imem_clk != NULL); - BUG_ON(kgsl_driver.ebi1_clk != NULL); - - kgsl_driver.pdev = pdev; - - setup_timer(&kgsl_driver.standby_timer, kgsl_do_standby_timer, 0); - wake_lock_init(&kgsl_driver.wake_lock, WAKE_LOCK_SUSPEND, "kgsl"); - - clk = clk_get(&pdev->dev, "grp_clk"); - if (IS_ERR(clk)) { - result = PTR_ERR(clk); - KGSL_DRV_ERR("clk_get(grp_clk) returned %d\n", result); - goto done; - } - kgsl_driver.grp_clk = clk; - - clk = clk_get(&pdev->dev, "grp_pclk"); - if (IS_ERR(clk)) { - KGSL_DRV_ERR("no grp_pclk, continuing\n"); - clk = NULL; - } - kgsl_driver.grp_pclk = clk; - - clk = clk_get(&pdev->dev, "imem_clk"); - if (IS_ERR(clk)) { - result = PTR_ERR(clk); - KGSL_DRV_ERR("clk_get(imem_clk) returned %d\n", result); - goto done; - } - kgsl_driver.imem_clk = clk; - - clk = clk_get(&pdev->dev, "ebi1_clk"); - if (IS_ERR(clk)) { - result = PTR_ERR(clk); - KGSL_DRV_ERR("clk_get(ebi1_clk) returned %d\n", result); - goto done; - } - kgsl_driver.ebi1_clk = clk; - - /*acquire interrupt */ - kgsl_driver.interrupt_num = platform_get_irq(pdev, 0); - if (kgsl_driver.interrupt_num <= 0) { - KGSL_DRV_ERR("platform_get_irq() returned %d\n", - kgsl_driver.interrupt_num); - result = -EINVAL; - goto done; - } - - result = request_irq(kgsl_driver.interrupt_num, kgsl_yamato_isr, - IRQF_TRIGGER_HIGH, DRIVER_NAME, NULL); - if (result) { - KGSL_DRV_ERR("request_irq(%d) returned %d\n", - kgsl_driver.interrupt_num, result); - goto done; - } - kgsl_driver.have_irq = 1; - disable_irq(kgsl_driver.interrupt_num); - - result = kgsl_yamato_config(&kgsl_driver.yamato_config, pdev); - if (result != 0) - goto done; - - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "kgsl_phys_memory"); - if (res == NULL) { - result = -EINVAL; - goto done; - } - - kgsl_driver.shmem.physbase = res->start; - kgsl_driver.shmem.size = resource_size(res); - - /* init memory apertures */ - result = kgsl_sharedmem_init(&kgsl_driver.shmem); - -done: - if (result) - kgsl_driver_cleanup(); - else - result = misc_register(&kgsl_driver.misc); - - return result; -} - -static int kgsl_platform_remove(struct platform_device *pdev) -{ - - kgsl_driver_cleanup(); - misc_deregister(&kgsl_driver.misc); - - return 0; -} - -static int kgsl_platform_suspend(struct platform_device *pdev, - pm_message_t state) -{ - mutex_lock(&kgsl_driver.mutex); - if (atomic_read(&kgsl_driver.open_count) > 0) { - if (kgsl_driver.active) - pr_err("%s: Suspending while active???\n", __func__); - } - mutex_unlock(&kgsl_driver.mutex); - return 0; -} - -static struct platform_driver kgsl_platform_driver = { - .probe = kgsl_platform_probe, - .remove = __devexit_p(kgsl_platform_remove), - .suspend = kgsl_platform_suspend, - .driver = { - .owner = THIS_MODULE, - .name = DRIVER_NAME - } -}; - -static int __init kgsl_mod_init(void) -{ - return platform_driver_register(&kgsl_platform_driver); -} - -static void __exit kgsl_mod_exit(void) -{ - platform_driver_unregister(&kgsl_platform_driver); -} - -module_init(kgsl_mod_init); -module_exit(kgsl_mod_exit); - -MODULE_AUTHOR("QUALCOMM"); -MODULE_DESCRIPTION("3D graphics driver for QSD8x50 and MSM7x27"); -MODULE_VERSION("1.0"); -MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS("platform:kgsl"); diff --git a/drivers/video/msm/gpu/kgsl/kgsl.h b/drivers/video/msm/gpu/kgsl/kgsl.h deleted file mode 100644 index e9f0d7cc..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* Copyright (c) 2008-2009 QUALCOMM USA, INC. -* -* All source code in this file is licensed under the following license -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* version 2 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, you can find it at http://www.fsf.org -*/ -#ifndef _GSL_DRIVER_H -#define _GSL_DRIVER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "kgsl_device.h" -#include "kgsl_sharedmem.h" - -#define DRIVER_NAME "kgsl" - -struct kgsl_driver { - struct miscdevice misc; - struct platform_device *pdev; - atomic_t open_count; - struct mutex mutex; - - int interrupt_num; - int have_irq; - - struct clk *grp_clk; - struct clk *grp_pclk; - struct clk *imem_clk; - struct clk *ebi1_clk; - - struct kgsl_devconfig yamato_config; - - uint32_t flags_debug; - - struct kgsl_sharedmem shmem; - struct kgsl_device yamato_device; - - struct list_head client_list; - - bool active; - int active_cnt; - struct timer_list standby_timer; - - struct wake_lock wake_lock; -}; - -extern struct kgsl_driver kgsl_driver; - -struct kgsl_mem_entry { - struct kgsl_memdesc memdesc; - struct file *pmem_file; - struct list_head list; - struct list_head free_list; - uint32_t free_timestamp; - - /* back pointer to private structure under whose context this - * allocation is made */ - struct kgsl_file_private *priv; -}; - -void kgsl_remove_mem_entry(struct kgsl_mem_entry *entry); - -#endif /* _GSL_DRIVER_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.c b/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.c deleted file mode 100644 index d8a16551..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.c +++ /dev/null @@ -1,105 +0,0 @@ -/* -* Copyright (c) 2008-2009 QUALCOMM USA, INC. -* -* All source code in this file is licensed under the following license -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* version 2 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, you can find it at http://www.fsf.org -*/ - -#include "kgsl.h" -#include "kgsl_device.h" -#include "kgsl_cmdstream.h" -#include "kgsl_sharedmem.h" - -int kgsl_cmdstream_init(struct kgsl_device *device) -{ - return 0; -} - -int kgsl_cmdstream_close(struct kgsl_device *device) -{ - return 0; -} - -uint32_t -kgsl_cmdstream_readtimestamp(struct kgsl_device *device, - enum kgsl_timestamp_type type) -{ - uint32_t timestamp = 0; - - KGSL_CMD_VDBG("enter (device_id=%d, type=%d)\n", device->id, type); - - if (type == KGSL_TIMESTAMP_CONSUMED) - KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device, - (unsigned int *)×tamp); - else if (type == KGSL_TIMESTAMP_RETIRED) - KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, - (unsigned int *)×tamp); - - rmb(); - - KGSL_CMD_VDBG("return %d\n", timestamp); - - return timestamp; -} - -int kgsl_cmdstream_check_timestamp(struct kgsl_device *device, - unsigned int timestamp) -{ - unsigned int ts_processed; - - ts_processed = kgsl_cmdstream_readtimestamp(device, - KGSL_TIMESTAMP_RETIRED); - return timestamp_cmp(ts_processed, timestamp); -} - -void kgsl_cmdstream_memqueue_drain(struct kgsl_device *device) -{ - struct kgsl_mem_entry *entry, *entry_tmp; - uint32_t ts_processed; - struct kgsl_ringbuffer *rb = &device->ringbuffer; - - /* get current EOP timestamp */ - ts_processed = - kgsl_cmdstream_readtimestamp(device, KGSL_TIMESTAMP_RETIRED); - - list_for_each_entry_safe(entry, entry_tmp, &rb->memqueue, free_list) { - /*NOTE: this assumes that the free list is sorted by - * timestamp, but I'm not yet sure that it is a valid - * assumption - */ - if (!timestamp_cmp(ts_processed, entry->free_timestamp)) - break; - KGSL_MEM_DBG("ts_processed %d ts_free %d gpuaddr %x)\n", - ts_processed, entry->free_timestamp, - entry->memdesc.gpuaddr); - kgsl_remove_mem_entry(entry); - } -} - -int -kgsl_cmdstream_freememontimestamp(struct kgsl_device *device, - struct kgsl_mem_entry *entry, - uint32_t timestamp, - enum kgsl_timestamp_type type) -{ - struct kgsl_ringbuffer *rb = &device->ringbuffer; - KGSL_MEM_DBG("enter (dev %p gpuaddr %x ts %d)\n", - device, entry->memdesc.gpuaddr, timestamp); - (void)type; /* unref. For now just use EOP timestamp */ - - list_add_tail(&entry->free_list, &rb->memqueue); - entry->free_timestamp = timestamp; - - return 0; -} diff --git a/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.h b/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.h deleted file mode 100644 index f81ef546..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_cmdstream.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef __KGSL_CMDSTREAM_H -#define __KGSL_CMDSTREAM_H - -#include -#include "kgsl_device.h" -#include "kgsl_log.h" - -#ifdef KGSL_DEVICE_SHADOW_MEMSTORE_TO_USER -#define KGSL_CMDSTREAM_USE_MEM_TIMESTAMP -#endif /* KGSL_DEVICE_SHADOW_MEMSTORE_TO_USER */ - -#ifdef KGSL_CMDSTREAM_USE_MEM_TIMESTAMP -#define KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device, data) \ - kgsl_sharedmem_read(&device->memstore, (data), \ - KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp), 4) -#else -#define KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device, data) \ - kgsl_yamato_regread(device, REG_CP_TIMESTAMP, (data)) -#endif /* KGSL_CMDSTREAM_USE_MEM_TIMESTAMP */ - -#define KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, data) \ - kgsl_sharedmem_read(&device->memstore, (data), \ - KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp), 4) - -/* Flags to control command packet settings */ -#define KGSL_CMD_FLAGS_PMODE 0x00000001 -#define KGSL_CMD_FLAGS_NO_TS_CMP 0x00000002 - -int kgsl_cmdstream_init(struct kgsl_device *device); - -int kgsl_cmdstream_close(struct kgsl_device *device); - -void kgsl_cmdstream_memqueue_drain(struct kgsl_device *device); - -uint32_t -kgsl_cmdstream_readtimestamp(struct kgsl_device *device, - enum kgsl_timestamp_type type); - -int kgsl_cmdstream_check_timestamp(struct kgsl_device *device, - unsigned int timestamp); - -int -kgsl_cmdstream_freememontimestamp(struct kgsl_device *device, - struct kgsl_mem_entry *entry, - uint32_t timestamp, - enum kgsl_timestamp_type type); - -static inline bool timestamp_cmp(unsigned int new, unsigned int old) -{ - int ts_diff = new - old; - return (ts_diff >= 0) || (ts_diff < -20000); -} - -#endif /* __KGSL_CMDSTREAM_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_device.h b/drivers/video/msm/gpu/kgsl/kgsl_device.h deleted file mode 100644 index c88e0cb5..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_device.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef _KGSL_DEVICE_H -#define _KGSL_DEVICE_H - -#include - -#include -#include -#include -#include - -#include "kgsl_drawctxt.h" -#include "kgsl_mmu.h" -#include "kgsl_ringbuffer.h" - -#define KGSL_CONTEXT_MAX 8 - -#define KGSL_TIMEOUT_NONE 0 -#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF - -#define KGSL_DEV_FLAGS_INITIALIZED0 0x00000001 -#define KGSL_DEV_FLAGS_INITIALIZED 0x00000002 -#define KGSL_DEV_FLAGS_STARTED 0x00000004 -#define KGSL_DEV_FLAGS_ACTIVE 0x00000008 - -#define KGSL_CHIPID_YAMATODX_REV21 0x20100 -#define KGSL_CHIPID_YAMATODX_REV211 0x20101 - -/* Private memory flags for use with memdesc->priv feild */ -#define KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH 0x00000001 -#define KGSL_MEMFLAGS_VMALLOC_MEM 0x00000002 - -#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000 -#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK))) - -struct kgsl_device; -struct platform_device; - - -struct kgsl_memregion { - unsigned char *mmio_virt_base; - unsigned int mmio_phys_base; - uint32_t gpu_base; - unsigned int sizebytes; -}; - -struct kgsl_device { - - unsigned int refcnt; - uint32_t flags; - enum kgsl_deviceid id; - unsigned int chip_id; - struct kgsl_memregion regspace; - struct kgsl_memdesc memstore; - - struct kgsl_mmu mmu; - struct kgsl_memregion gmemspace; - struct kgsl_ringbuffer ringbuffer; - unsigned int drawctxt_count; - struct kgsl_drawctxt *drawctxt_active; - struct kgsl_drawctxt drawctxt[KGSL_CONTEXT_MAX]; - - wait_queue_head_t ib1_wq; -}; - -struct kgsl_devconfig { - struct kgsl_memregion regspace; - - unsigned int mmu_config; - uint32_t mpu_base; - int mpu_range; - uint32_t va_base; - unsigned int va_range; - - struct kgsl_memregion gmemspace; -}; - -int kgsl_yamato_start(struct kgsl_device *device, uint32_t flags); - -int kgsl_yamato_stop(struct kgsl_device *device); - -bool kgsl_yamato_is_idle(struct kgsl_device *device); - -int kgsl_yamato_idle(struct kgsl_device *device, unsigned int timeout); - -int kgsl_yamato_getproperty(struct kgsl_device *device, - enum kgsl_property_type type, void *value, - unsigned int sizebytes); - -int kgsl_yamato_regread(struct kgsl_device *device, unsigned int offsetwords, - unsigned int *value); - -int kgsl_yamato_regwrite(struct kgsl_device *device, unsigned int offsetwords, - unsigned int value); - -int kgsl_yamato_waittimestamp(struct kgsl_device *device, - unsigned int timestamp, unsigned int timeout); - - -int kgsl_yamato_init(struct kgsl_device *, struct kgsl_devconfig *); - -int kgsl_yamato_close(struct kgsl_device *device); - -int kgsl_yamato_runpending(struct kgsl_device *device); - -int __init kgsl_yamato_config(struct kgsl_devconfig *, - struct platform_device *pdev); - -void kgsl_register_dump(struct kgsl_device *device); - -int kgsl_yamato_setup_pt(struct kgsl_device *device, - struct kgsl_pagetable *pagetable); -int kgsl_yamato_cleanup_pt(struct kgsl_device *device, - struct kgsl_pagetable *pagetable); -#ifdef CONFIG_GPU_MSM_KGSL_MMU -int kgsl_yamato_setstate(struct kgsl_device *device, uint32_t flags); -#else -static inline int kgsl_yamato_setstate(struct kgsl_device *device, uint32_t flags) -{ return 0; } -#endif - -irqreturn_t kgsl_yamato_isr(int irq, void *data); - -#endif /* _KGSL_DEVICE_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.c b/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.c deleted file mode 100644 index 3e5262e8..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.c +++ /dev/null @@ -1,1823 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include -#include - -#include "kgsl_drawctxt.h" - -#include "yamato_reg.h" -#include "kgsl.h" -#include "kgsl_log.h" -#include "kgsl_pm4types.h" -#include "kgsl_cmdstream.h" - -/* -* -* Memory Map for Register, Constant & Instruction Shadow, and Command Buffers -* (34.5KB) -* -* +---------------------+------------+-------------+---+---------------------+ -* | ALU Constant Shadow | Reg Shadow | C&V Buffers |Tex| Shader Instr Shadow | -* +---------------------+------------+-------------+---+---------------------+ -* ________________________________/ \____________________ -* / | -* +--------------+-----------+------+-----------+------------------------+ -* | Restore Regs | Save Regs | Quad | Gmem Save | Gmem Restore | unused | -* +--------------+-----------+------+-----------+------------------------+ -* -* 8K - ALU Constant Shadow (8K aligned) -* 4K - H/W Register Shadow (8K aligned) -* 4K - Command and Vertex Buffers -* - Indirect command buffer : Const/Reg restore -* - includes Loop & Bool const shadows -* - Indirect command buffer : Const/Reg save -* - Quad vertices & texture coordinates -* - Indirect command buffer : Gmem save -* - Indirect command buffer : Gmem restore -* - Unused (padding to 8KB boundary) -* <1K - Texture Constant Shadow (768 bytes) (8K aligned) -* 18K - Shader Instruction Shadow -* - 6K vertex (32 byte aligned) -* - 6K pixel (32 byte aligned) -* - 6K shared (32 byte aligned) -* -* Note: Reading constants into a shadow, one at a time using REG_TO_MEM, takes -* 3 DWORDS per DWORD transfered, plus 1 DWORD for the shadow, for a total of -* 16 bytes per constant. If the texture constants were transfered this way, -* the Command & Vertex Buffers section would extend past the 16K boundary. -* By moving the texture constant shadow area to start at 16KB boundary, we -* only require approximately 40 bytes more memory, but are able to use the -* LOAD_CONSTANT_CONTEXT shadowing feature for the textures, speeding up -* context switching. -* -* [Using LOAD_CONSTANT_CONTEXT shadowing feature for the Loop and/or Bool -* constants would require an additional 8KB each, for alignment.] -* -*/ - -/* Constants */ - -#define ALU_CONSTANTS 2048 /* DWORDS */ -#define NUM_REGISTERS 1024 /* DWORDS */ -#ifdef DISABLE_SHADOW_WRITES -#define CMD_BUFFER_LEN 9216 /* DWORDS */ -#else -#define CMD_BUFFER_LEN 3072 /* DWORDS */ -#endif -#define TEX_CONSTANTS (32*6) /* DWORDS */ -#define BOOL_CONSTANTS 8 /* DWORDS */ -#define LOOP_CONSTANTS 56 /* DWORDS */ -#define SHADER_INSTRUCT_LOG2 9U /* 2^n == SHADER_INSTRUCTIONS */ - -#if defined(PM4_IM_STORE) -/* 96-bit instructions */ -#define SHADER_INSTRUCT (1<= 0x10000) { - exp += 16; - u >>= 16; - } - if (u >= 0x100) { - exp += 8; - u >>= 8; - } - if (u >= 0x10) { - exp += 4; - u >>= 4; - } - if (u >= 0x4) { - exp += 2; - u >>= 2; - } - if (u >= 0x2) { - exp += 1; - u >>= 1; - } - - /* Calculate fraction */ - frac = (uintval & (~(1 << exp))) << (23 - exp); - - /* Exp is biased by 127 and shifted 23 bits */ - exp = (exp + 127) << 23; - - return exp | frac; -} - -/* context save (gmem -> sys) */ - -/* pre-compiled vertex shader program -* -* attribute vec4 P; -* void main(void) -* { -* gl_Position = P; -* } -*/ -#define GMEM2SYS_VTX_PGM_LEN 0x12 - -static unsigned int gmem2sys_vtx_pgm[GMEM2SYS_VTX_PGM_LEN] = { - 0x00011003, 0x00001000, 0xc2000000, - 0x00001004, 0x00001000, 0xc4000000, - 0x00001005, 0x00002000, 0x00000000, - 0x1cb81000, 0x00398a88, 0x00000003, - 0x140f803e, 0x00000000, 0xe2010100, - 0x14000000, 0x00000000, 0xe2000000 -}; - -/* pre-compiled fragment shader program -* -* precision highp float; -* uniform vec4 clear_color; -* void main(void) -* { -* gl_FragColor = clear_color; -* } -*/ - -#define GMEM2SYS_FRAG_PGM_LEN 0x0c - -static unsigned int gmem2sys_frag_pgm[GMEM2SYS_FRAG_PGM_LEN] = { - 0x00000000, 0x1002c400, 0x10000000, - 0x00001003, 0x00002000, 0x00000000, - 0x140f8000, 0x00000000, 0x22000000, - 0x14000000, 0x00000000, 0xe2000000 -}; - -/* context restore (sys -> gmem) */ -/* pre-compiled vertex shader program -* -* attribute vec4 position; -* attribute vec4 texcoord; -* varying vec4 texcoord0; -* void main() -* { -* gl_Position = position; -* texcoord0 = texcoord; -* } -*/ - -#define SYS2GMEM_VTX_PGM_LEN 0x18 - -static unsigned int sys2gmem_vtx_pgm[SYS2GMEM_VTX_PGM_LEN] = { - 0x00052003, 0x00001000, 0xc2000000, 0x00001005, - 0x00001000, 0xc4000000, 0x00001006, 0x10071000, - 0x20000000, 0x18981000, 0x0039ba88, 0x00000003, - 0x12982000, 0x40257b08, 0x00000002, 0x140f803e, - 0x00000000, 0xe2010100, 0x140f8000, 0x00000000, - 0xe2020200, 0x14000000, 0x00000000, 0xe2000000 -}; - -/* pre-compiled fragment shader program -* -* precision mediump float; -* uniform sampler2D tex0; -* varying vec4 texcoord0; -* void main() -* { -* gl_FragColor = texture2D(tex0, texcoord0.xy); -* } -*/ - -#define SYS2GMEM_FRAG_PGM_LEN 0x0f - -static unsigned int sys2gmem_frag_pgm[SYS2GMEM_FRAG_PGM_LEN] = { - 0x00011002, 0x00001000, 0xc4000000, 0x00001003, - 0x10041000, 0x20000000, 0x10000001, 0x1ffff688, - 0x00000002, 0x140f8000, 0x00000000, 0xe2000000, - 0x14000000, 0x00000000, 0xe2000000 -}; - -/* shader texture constants (sysmem -> gmem) */ -#define SYS2GMEM_TEX_CONST_LEN 6 - -static unsigned int sys2gmem_tex_const[SYS2GMEM_TEX_CONST_LEN] = { - /* Texture, FormatXYZW=Unsigned, ClampXYZ=Wrap/Repeat, - * RFMode=ZeroClamp-1, Dim=1:2d - */ - 0x00000002, /* Pitch = TBD */ - - /* Format=6:8888_WZYX, EndianSwap=0:None, ReqSize=0:256bit, DimHi=0, - * NearestClamp=1:OGL Mode - */ - 0x00000800, /* Address[31:12] = TBD */ - - /* Width, Height, EndianSwap=0:None */ - 0, /* Width & Height = TBD */ - - /* NumFormat=0:RF, DstSelXYZW=XYZW, ExpAdj=0, MagFilt=MinFilt=0:Point, - * Mip=2:BaseMap - */ - 0 << 1 | 1 << 4 | 2 << 7 | 3 << 10 | 2 << 23, - - /* VolMag=VolMin=0:Point, MinMipLvl=0, MaxMipLvl=1, LodBiasH=V=0, - * Dim3d=0 - */ - 0, - - /* BorderColor=0:ABGRBlack, ForceBC=0:diable, TriJuice=0, Aniso=0, - * Dim=1:2d, MipPacking=0 - */ - 1 << 9 /* Mip Address[31:12] = TBD */ -}; - -/* quad for copying GMEM to context shadow */ -#define QUAD_LEN 12 - -static unsigned int gmem_copy_quad[QUAD_LEN] = { - 0x00000000, 0x00000000, 0x3f800000, - 0x00000000, 0x00000000, 0x3f800000, - 0x00000000, 0x00000000, 0x3f800000, - 0x00000000, 0x00000000, 0x3f800000 -}; - -#define TEXCOORD_LEN 8 - -static unsigned int gmem_copy_texcoord[TEXCOORD_LEN] = { - 0x00000000, 0x3f800000, - 0x3f800000, 0x3f800000, - 0x00000000, 0x00000000, - 0x3f800000, 0x00000000 -}; - -#define NUM_COLOR_FORMATS 13 - -static enum SURFACEFORMAT surface_format_table[NUM_COLOR_FORMATS] = { - FMT_4_4_4_4, /* COLORX_4_4_4_4 */ - FMT_1_5_5_5, /* COLORX_1_5_5_5 */ - FMT_5_6_5, /* COLORX_5_6_5 */ - FMT_8, /* COLORX_8 */ - FMT_8_8, /* COLORX_8_8 */ - FMT_8_8_8_8, /* COLORX_8_8_8_8 */ - FMT_8_8_8_8, /* COLORX_S8_8_8_8 */ - FMT_16_FLOAT, /* COLORX_16_FLOAT */ - FMT_16_16_FLOAT, /* COLORX_16_16_FLOAT */ - FMT_16_16_16_16_FLOAT, /* COLORX_16_16_16_16_FLOAT */ - FMT_32_FLOAT, /* COLORX_32_FLOAT */ - FMT_32_32_FLOAT, /* COLORX_32_32_FLOAT */ - FMT_32_32_32_32_FLOAT, /* COLORX_32_32_32_32_FLOAT */ -}; - -static unsigned int format2bytesperpixel[NUM_COLOR_FORMATS] = { - 2, /* COLORX_4_4_4_4 */ - 2, /* COLORX_1_5_5_5 */ - 2, /* COLORX_5_6_5 */ - 1, /* COLORX_8 */ - 2, /* COLORX_8_8 8*/ - 4, /* COLORX_8_8_8_8 */ - 4, /* COLORX_S8_8_8_8 */ - 2, /* COLORX_16_FLOAT */ - 4, /* COLORX_16_16_FLOAT */ - 8, /* COLORX_16_16_16_16_FLOAT */ - 4, /* COLORX_32_FLOAT */ - 8, /* COLORX_32_32_FLOAT */ - 16, /* COLORX_32_32_32_32_FLOAT */ -}; - -/* shader linkage info */ -#define SHADER_CONST_ADDR (11 * 6 + 3) - -/* gmem command buffer length */ -#define PM4_REG(reg) ((0x4 << 16) | (GSL_HAL_SUBBLOCK_OFFSET(reg))) - -/* functions */ -static void config_gmemsize(struct gmem_shadow_t *shadow, int gmem_size) -{ - int w = 64, h = 64; /* 16KB surface, minimum */ - - shadow->format = COLORX_8_8_8_8; - /* convert from bytes to 32-bit words */ - gmem_size = (gmem_size + 3) / 4; - - /* find the right surface size, close to a square. */ - while (w * h < gmem_size) - if (w < h) - w *= 2; - else - h *= 2; - - shadow->width = w; - shadow->pitch = w; - shadow->height = h; - shadow->gmem_pitch = shadow->pitch; - - shadow->size = shadow->pitch * shadow->height * 4; -} - -static unsigned int gpuaddr(unsigned int *cmd, struct kgsl_memdesc *memdesc) -{ - return memdesc->gpuaddr + ((char *)cmd - (char *)memdesc->hostptr); -} - -static void -create_ib1(struct kgsl_drawctxt *drawctxt, unsigned int *cmd, - unsigned int *start, unsigned int *end) -{ - cmd[0] = PM4_HDR_INDIRECT_BUFFER_PFD; - cmd[1] = gpuaddr(start, &drawctxt->gpustate); - cmd[2] = end - start; -} - -static unsigned int *program_shader(unsigned int *cmds, int vtxfrag, - unsigned int *shader_pgm, int dwords) -{ - /* load the patched vertex shader stream */ - *cmds++ = pm4_type3_packet(PM4_IM_LOAD_IMMEDIATE, 2 + dwords); - /* 0=vertex shader, 1=fragment shader */ - *cmds++ = vtxfrag; - /* instruction start & size (in 32-bit words) */ - *cmds++ = ((0 << 16) | dwords); - - memcpy(cmds, shader_pgm, dwords << 2); - cmds += dwords; - - return cmds; -} - -static unsigned int *reg_to_mem(unsigned int *cmds, uint32_t dst, - uint32_t src, int dwords) -{ - while (dwords-- > 0) { - *cmds++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmds++ = src++; - *cmds++ = dst; - dst += 4; - } - - return cmds; -} - -#ifdef DISABLE_SHADOW_WRITES - -static void build_reg_to_mem_range(unsigned int start, unsigned int end, - unsigned int **cmd, - struct kgsl_drawctxt *drawctxt) -{ - unsigned int i = start; - - for (i = start; i <= end; i++) { - *(*cmd)++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *(*cmd)++ = i | (1 << 30); - *(*cmd)++ = - ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) + - (i - 0x2000) * 4; - } -} - -#endif - -/* chicken restore */ -static unsigned int *build_chicken_restore_cmds(struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx) -{ - unsigned int *start = ctx->cmd; - unsigned int *cmds = start; - - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0; - - *cmds++ = pm4_type0_packet(REG_TP0_CHICKEN, 1); - ctx->chicken_restore = gpuaddr(cmds, &drawctxt->gpustate); - *cmds++ = 0x00000000; - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->chicken_restore, start, cmds); - - return cmds; -} - -/* save h/w regs, alu constants, texture contants, etc. ... -* requires: bool_shadow_gpuaddr, loop_shadow_gpuaddr -*/ -static void build_regsave_cmds(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx) -{ - unsigned int *start = ctx->cmd; - unsigned int *cmd = start; - unsigned int pm_override1; - - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE1, &pm_override1); - - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - -#ifdef DISABLE_SHADOW_WRITES - /* Make sure the HW context has the correct register values - * before reading them. */ - *cmd++ = pm4_type3_packet(PM4_CONTEXT_UPDATE, 1); - *cmd++ = 0; -#endif - - /* Enable clock override for REG_FIFOS_SCLK */ - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmd++ = pm_override1 | (1 << 6); - -#ifdef DISABLE_SHADOW_WRITES - /* Write HW registers into shadow */ - build_reg_to_mem_range(REG_RB_SURFACE_INFO, REG_RB_DEPTH_INFO, &cmd, - drawctxt); - build_reg_to_mem_range(REG_COHER_DEST_BASE_0, - REG_PA_SC_SCREEN_SCISSOR_BR, &cmd, drawctxt); - build_reg_to_mem_range(REG_PA_SC_WINDOW_OFFSET, - REG_PA_SC_WINDOW_SCISSOR_BR, &cmd, drawctxt); - build_reg_to_mem_range(REG_VGT_MAX_VTX_INDX, REG_RB_FOG_COLOR, &cmd, - drawctxt); - build_reg_to_mem_range(REG_RB_STENCILREFMASK_BF, - REG_PA_CL_VPORT_ZOFFSET, &cmd, drawctxt); - build_reg_to_mem_range(REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1, &cmd, - drawctxt); - build_reg_to_mem_range(REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL, &cmd, - drawctxt); - build_reg_to_mem_range(REG_PA_SU_POINT_SIZE, REG_PA_SC_LINE_STIPPLE, - &cmd, drawctxt); - build_reg_to_mem_range(REG_PA_SC_VIZ_QUERY, REG_PA_SC_VIZ_QUERY, &cmd, - drawctxt); - build_reg_to_mem_range(REG_PA_SC_LINE_CNTL, REG_SQ_PS_CONST, &cmd, - drawctxt); - build_reg_to_mem_range(REG_PA_SC_AA_MASK, REG_PA_SC_AA_MASK, &cmd, - drawctxt); - build_reg_to_mem_range(REG_VGT_VERTEX_REUSE_BLOCK_CNTL, - REG_RB_DEPTH_CLEAR, &cmd, drawctxt); - build_reg_to_mem_range(REG_RB_SAMPLE_COUNT_CTL, REG_RB_COLOR_DEST_MASK, - &cmd, drawctxt); - build_reg_to_mem_range(REG_PA_SU_POLY_OFFSET_FRONT_SCALE, - REG_PA_SU_POLY_OFFSET_BACK_OFFSET, &cmd, - drawctxt); - - /* Copy ALU constants */ - cmd = - reg_to_mem(cmd, (drawctxt->gpustate.gpuaddr) & 0xFFFFE000, - REG_SQ_CONSTANT_0, ALU_CONSTANTS); - - /* Copy Tex constants */ - cmd = - reg_to_mem(cmd, - (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000, - REG_SQ_FETCH_0, TEX_CONSTANTS); -#else - - /* Insert a wait for idle packet before reading the registers. - * This is to fix a hang/reset seen during stress testing. In this - * hang, CP encountered a timeout reading SQ's boolean constant - * register. There is logic in the HW that blocks reading of this - * register when the SQ block is not idle, which we believe is - * contributing to the hang.*/ - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - /* H/w registers are already shadowed; just need to disable shadowing - * to prevent corruption. - */ - *cmd++ = pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, 3); - *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000; - *cmd++ = 4 << 16; /* regs, start=0 */ - *cmd++ = 0x0; /* count = 0 */ - - /* ALU constants are already shadowed; just need to disable shadowing - * to prevent corruption. - */ - *cmd++ = pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, 3); - *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000; - *cmd++ = 0 << 16; /* ALU, start=0 */ - *cmd++ = 0x0; /* count = 0 */ - - /* Tex constants are already shadowed; just need to disable shadowing - * to prevent corruption. - */ - *cmd++ = pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, 3); - *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000; - *cmd++ = 1 << 16; /* Tex, start=0 */ - *cmd++ = 0x0; /* count = 0 */ -#endif - - /* Need to handle some of the registers separately */ - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_SQ_GPR_MANAGEMENT; - *cmd++ = ctx->reg_values[0]; - - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_TP0_CHICKEN; - *cmd++ = ctx->reg_values[1]; - - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_RBBM_PM_OVERRIDE1; - *cmd++ = ctx->reg_values[2]; - - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_RBBM_PM_OVERRIDE2; - *cmd++ = ctx->reg_values[3]; - - /* Copy Boolean constants */ - cmd = reg_to_mem(cmd, ctx->bool_shadow, REG_SQ_CF_BOOLEANS, - BOOL_CONSTANTS); - - /* Copy Loop constants */ - cmd = reg_to_mem(cmd, ctx->loop_shadow, REG_SQ_CF_LOOP, LOOP_CONSTANTS); - - /* Restore RBBM_PM_OVERRIDE1 */ - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmd++ = pm_override1; - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->reg_save, start, cmd); - - ctx->cmd = cmd; -} - -/*copy colour, depth, & stencil buffers from graphics memory to system memory*/ -static unsigned int *build_gmem2sys_cmds(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx, - struct gmem_shadow_t *shadow) -{ - unsigned int *cmds = shadow->gmem_save_commands; - unsigned int *start = cmds; - unsigned int pm_override1; - /* Calculate the new offset based on the adjusted base */ - unsigned int bytesperpixel = format2bytesperpixel[shadow->format]; - unsigned int addr = - (shadow->gmemshadow.gpuaddr + shadow->offset * bytesperpixel); - unsigned int offset = (addr - (addr & 0xfffff000)) / bytesperpixel; - - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE1, &pm_override1); - - /* Store TP0_CHICKEN register */ - *cmds++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmds++ = REG_TP0_CHICKEN; - if (ctx) - *cmds++ = ctx->chicken_restore; - else - cmds++; - - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0; - - /* Enable clock override for REG_FIFOS_SCLK */ - *cmds++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmds++ = pm_override1 | (1 << 6); - - /* Set TP0_CHICKEN to zero */ - *cmds++ = pm4_type0_packet(REG_TP0_CHICKEN, 1); - *cmds++ = 0x00000000; - - /* Set PA_SC_AA_CONFIG to 0 */ - *cmds++ = pm4_type0_packet(REG_PA_SC_AA_CONFIG, 1); - *cmds++ = 0x00000000; - - /* program shader */ - - /* load shader vtx constants ... 5 dwords */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 4); - *cmds++ = (0x1 << 16) | SHADER_CONST_ADDR; - *cmds++ = 0; - /* valid(?) vtx constant flag & addr */ - *cmds++ = shadow->quad_vertices.gpuaddr | 0x3; - /* limit = 12 dwords */ - *cmds++ = 0x00000030; - - /* Invalidate L2 cache to make sure vertices are updated */ - *cmds++ = pm4_type0_packet(REG_TC_CNTL_STATUS, 1); - *cmds++ = 0x1; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 4); - *cmds++ = PM4_REG(REG_VGT_MAX_VTX_INDX); - *cmds++ = 0x00ffffff; /* REG_VGT_MAX_VTX_INDX */ - *cmds++ = 0x0; /* REG_VGT_MIN_VTX_INDX */ - *cmds++ = 0x00000000; /* REG_VGT_INDX_OFFSET */ - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SC_AA_MASK); - *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */ - - /* load the patched vertex shader stream */ - cmds = program_shader(cmds, 0, gmem2sys_vtx_pgm, GMEM2SYS_VTX_PGM_LEN); - - /* Load the patched fragment shader stream */ - cmds = - program_shader(cmds, 1, gmem2sys_frag_pgm, GMEM2SYS_FRAG_PGM_LEN); - - /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_SQ_PROGRAM_CNTL); - *cmds++ = 0x10010001; - *cmds++ = 0x00000008; - - /* resolve */ - - /* PA_CL_VTE_CNTL */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_CL_VTE_CNTL); - /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */ - *cmds++ = 0x00000b00; - - /* program surface info */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_RB_SURFACE_INFO); - *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */ - - /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0, - * Base=gmem_base - */ - /* gmem base assumed 4K aligned. */ - if (ctx) { - BUG_ON(ctx->gmem_base & 0xFFF); - *cmds++ = - (shadow-> - format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | ctx-> - gmem_base; - } else { - unsigned int temp = *cmds; - *cmds++ = (temp & ~RB_COLOR_INFO__COLOR_FORMAT_MASK) | - (shadow->format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT); - } - - /* disable Z */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_DEPTHCONTROL); - *cmds++ = 0; - - /* set REG_PA_SU_SC_MODE_CNTL - * Front_ptype = draw triangles - * Back_ptype = draw triangles - * Provoking vertex = last - */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SU_SC_MODE_CNTL); - *cmds++ = 0x00080240; - - /* Use maximum scissor values -- quad vertices already have the - * correct bounds */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_SC_SCREEN_SCISSOR_TL); - *cmds++ = (0 << 16) | 0; - *cmds++ = (0x1fff << 16) | (0x1fff); - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_SC_WINDOW_SCISSOR_TL); - *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0); - *cmds++ = (0x1fff << 16) | (0x1fff); - - /* load the viewport so that z scale = clear depth and - * z offset = 0.0f - */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_CL_VPORT_ZSCALE); - *cmds++ = 0xbf800000; /* -1.0f */ - *cmds++ = 0x0; - - /* load the stencil ref value - * $AAM - do this later - */ - - /* load the COPY state */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 6); - *cmds++ = PM4_REG(REG_RB_COPY_CONTROL); - *cmds++ = 0; /* RB_COPY_CONTROL */ - *cmds++ = addr & 0xfffff000; /* RB_COPY_DEST_BASE */ - *cmds++ = shadow->pitch >> 5; /* RB_COPY_DEST_PITCH */ - - /* Endian=none, Linear, Format=RGBA8888,Swap=0,!Dither, - * MaskWrite:R=G=B=A=1 - */ - *cmds++ = 0x0003c008 | - (shadow->format << RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT); - /* Make sure we stay in offsetx field. */ - BUG_ON(offset & 0xfffff000); - *cmds++ = offset; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_MODECONTROL); - *cmds++ = 0x6; /* EDRAM copy */ - - /* queue the draw packet */ - *cmds++ = pm4_type3_packet(PM4_DRAW_INDX, 2); - *cmds++ = 0; /* viz query info. */ - /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */ - *cmds++ = 0x00030088; - - /* Restore RBBM_PM_OVERRIDE1 */ - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0; - *cmds++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmds++ = pm_override1; - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, shadow->gmem_save, start, cmds); - - return cmds; -} - -/* context restore */ - -/*copy colour, depth, & stencil buffers from system memory to graphics memory*/ -static unsigned int *build_sys2gmem_cmds(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx, - struct gmem_shadow_t *shadow) -{ - unsigned int *cmds = shadow->gmem_restore_commands; - unsigned int *start = cmds; - unsigned int pm_override1; - - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE1, &pm_override1); - - /* Store TP0_CHICKEN register */ - *cmds++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmds++ = REG_TP0_CHICKEN; - if (ctx) - *cmds++ = ctx->chicken_restore; - else - cmds++; - - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0; - - /* Enable clock override for REG_FIFOS_SCLK */ - *cmds++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmds++ = pm_override1 | (1 << 6); - - /* Set TP0_CHICKEN to zero */ - *cmds++ = pm4_type0_packet(REG_TP0_CHICKEN, 1); - *cmds++ = 0x00000000; - - /* Set PA_SC_AA_CONFIG to 0 */ - *cmds++ = pm4_type0_packet(REG_PA_SC_AA_CONFIG, 1); - *cmds++ = 0x00000000; - /* shader constants */ - - /* vertex buffer constants */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 7); - - *cmds++ = (0x1 << 16) | (9 * 6); - /* valid(?) vtx constant flag & addr */ - *cmds++ = shadow->quad_vertices.gpuaddr | 0x3; - /* limit = 12 dwords */ - *cmds++ = 0x00000030; - /* valid(?) vtx constant flag & addr */ - *cmds++ = shadow->quad_texcoords.gpuaddr | 0x3; - /* limit = 8 dwords */ - *cmds++ = 0x00000020; - *cmds++ = 0; - *cmds++ = 0; - - /* Invalidate L2 cache to make sure vertices are updated */ - *cmds++ = pm4_type0_packet(REG_TC_CNTL_STATUS, 1); - *cmds++ = 0x1; - - cmds = program_shader(cmds, 0, sys2gmem_vtx_pgm, SYS2GMEM_VTX_PGM_LEN); - - /* Load the patched fragment shader stream */ - cmds = - program_shader(cmds, 1, sys2gmem_frag_pgm, SYS2GMEM_FRAG_PGM_LEN); - - /* SQ_PROGRAM_CNTL / SQ_CONTEXT_MISC */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_SQ_PROGRAM_CNTL); - *cmds++ = 0x10030002; - *cmds++ = 0x00000008; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SC_AA_MASK); - *cmds++ = 0x0000ffff; /* REG_PA_SC_AA_MASK */ - - /* PA_SC_VIZ_QUERY */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SC_VIZ_QUERY); - *cmds++ = 0x0; /*REG_PA_SC_VIZ_QUERY */ - - /* RB_COLORCONTROL */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_COLORCONTROL); - *cmds++ = 0x00000c20; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 4); - *cmds++ = PM4_REG(REG_VGT_MAX_VTX_INDX); - *cmds++ = 0x00ffffff; /* mmVGT_MAX_VTX_INDX */ - *cmds++ = 0x0; /* mmVGT_MIN_VTX_INDX */ - *cmds++ = 0x00000000; /* mmVGT_INDX_OFFSET */ - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_VGT_VERTEX_REUSE_BLOCK_CNTL); - *cmds++ = 0x00000002; /* mmVGT_VERTEX_REUSE_BLOCK_CNTL */ - *cmds++ = 0x00000002; /* mmVGT_OUT_DEALLOC_CNTL */ - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_SQ_INTERPOLATOR_CNTL); - //*cmds++ = 0x0000ffff; //mmSQ_INTERPOLATOR_CNTL - *cmds++ = 0xffffffff; //mmSQ_INTERPOLATOR_CNTL - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SC_AA_CONFIG); - *cmds++ = 0x00000000; /* REG_PA_SC_AA_CONFIG */ - - /* set REG_PA_SU_SC_MODE_CNTL - * Front_ptype = draw triangles - * Back_ptype = draw triangles - * Provoking vertex = last - */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_SU_SC_MODE_CNTL); - *cmds++ = 0x00080240; - - /* texture constants */ - *cmds++ = - pm4_type3_packet(PM4_SET_CONSTANT, (SYS2GMEM_TEX_CONST_LEN + 1)); - *cmds++ = (0x1 << 16) | (0 * 6); - memcpy(cmds, sys2gmem_tex_const, SYS2GMEM_TEX_CONST_LEN << 2); - cmds[0] |= (shadow->pitch >> 5) << 22; - cmds[1] |= - shadow->gmemshadow.gpuaddr | surface_format_table[shadow->format]; - cmds[2] |= - (shadow->width + shadow->offset_x - 1) | (shadow->height + - shadow->offset_y - - 1) << 13; - cmds += SYS2GMEM_TEX_CONST_LEN; - - /* program surface info */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_RB_SURFACE_INFO); - *cmds++ = shadow->gmem_pitch; /* pitch, MSAA = 1 */ - - /* RB_COLOR_INFO Endian=none, Linear, Format=RGBA8888, Swap=0, - * Base=gmem_base - */ - if (ctx) - *cmds++ = - (shadow-> - format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT) | ctx-> - gmem_base; - else { - unsigned int temp = *cmds; - *cmds++ = (temp & ~RB_COLOR_INFO__COLOR_FORMAT_MASK) | - (shadow->format << RB_COLOR_INFO__COLOR_FORMAT__SHIFT); - } - - /* RB_DEPTHCONTROL */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_DEPTHCONTROL); - *cmds++ = 0; /* disable Z */ - - /* Use maximum scissor values -- quad vertices already - * have the correct bounds */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_SC_SCREEN_SCISSOR_TL); - *cmds++ = (0 << 16) | 0; - *cmds++ = ((0x1fff) << 16) | 0x1fff; - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_SC_WINDOW_SCISSOR_TL); - *cmds++ = (unsigned int)((1U << 31) | (0 << 16) | 0); - *cmds++ = ((0x1fff) << 16) | 0x1fff; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_PA_CL_VTE_CNTL); - /* disable X/Y/Z transforms, X/Y/Z are premultiplied by W */ - *cmds++ = 0x00000b00; - - /*load the viewport so that z scale = clear depth and z offset = 0.0f */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_PA_CL_VPORT_ZSCALE); - *cmds++ = 0xbf800000; - *cmds++ = 0x0; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_COLOR_MASK); - *cmds++ = 0x0000000f; /* R = G = B = 1:enabled */ - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_COLOR_DEST_MASK); - *cmds++ = 0xffffffff; - - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 3); - *cmds++ = PM4_REG(REG_SQ_WRAPPING_0); - *cmds++ = 0x00000000; - *cmds++ = 0x00000000; - - /* load the stencil ref value - * $AAM - do this later - */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = PM4_REG(REG_RB_MODECONTROL); - /* draw pixels with color and depth/stencil component */ - *cmds++ = 0x4; - - /* queue the draw packet */ - *cmds++ = pm4_type3_packet(PM4_DRAW_INDX, 2); - *cmds++ = 0; /* viz query info. */ - /* PrimType=RectList, NumIndices=3, SrcSel=AutoIndex */ - *cmds++ = 0x00030088; - - /* Restore RBBM_PM_OVERRIDE1 */ - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0; - *cmds++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmds++ = pm_override1; - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, shadow->gmem_restore, start, cmds); - - return cmds; -} - -/* restore h/w regs, alu constants, texture constants, etc. ... */ -static unsigned *reg_range(unsigned int *cmd, unsigned int start, - unsigned int end) -{ - *cmd++ = PM4_REG(start); /* h/w regs, start addr */ - *cmd++ = end - start + 1; /* count */ - return cmd; -} - -static void build_regrestore_cmds(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx) -{ - unsigned int *start = ctx->cmd; - unsigned int *cmd = start; - unsigned int pm_override1; - - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE1, &pm_override1); - - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - - /* Enable clock override for REG_FIFOS_SCLK */ - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmd++ = pm_override1 | (1 << 6); - - /* H/W Registers */ - /* deferred pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, ???); */ - cmd++; -#ifdef DISABLE_SHADOW_WRITES - /* Force mismatch */ - *cmd++ = ((drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000) | 1; -#else - *cmd++ = (drawctxt->gpustate.gpuaddr + REG_OFFSET) & 0xFFFFE000; -#endif - - cmd = reg_range(cmd, REG_RB_SURFACE_INFO, REG_PA_SC_SCREEN_SCISSOR_BR); - cmd = reg_range(cmd, REG_PA_SC_WINDOW_OFFSET, - REG_PA_SC_WINDOW_SCISSOR_BR); - cmd = reg_range(cmd, REG_VGT_MAX_VTX_INDX, REG_PA_CL_VPORT_ZOFFSET); - cmd = reg_range(cmd, REG_SQ_PROGRAM_CNTL, REG_SQ_WRAPPING_1); - cmd = reg_range(cmd, REG_RB_DEPTHCONTROL, REG_RB_MODECONTROL); - cmd = reg_range(cmd, REG_PA_SU_POINT_SIZE, - REG_PA_SC_VIZ_QUERY); /*REG_VGT_ENHANCE */ - cmd = reg_range(cmd, REG_PA_SC_LINE_CNTL, REG_RB_COLOR_DEST_MASK); - cmd = reg_range(cmd, REG_PA_SU_POLY_OFFSET_FRONT_SCALE, - REG_PA_SU_POLY_OFFSET_BACK_OFFSET); - - /* Now we know how many register blocks we have, we can compute command - * length - */ - start[4] = - pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, (cmd - start) - 5); - /* Enable shadowing for the entire register block. */ -#ifdef DISABLE_SHADOW_WRITES - start[6] |= (0 << 24) | (4 << 16); /* Disable shadowing. */ -#else - start[6] |= (1 << 24) | (4 << 16); -#endif - - /* Need to handle some of the registers separately */ - *cmd++ = pm4_type0_packet(REG_SQ_GPR_MANAGEMENT, 1); - ctx->reg_values[0] = gpuaddr(cmd, &drawctxt->gpustate); - *cmd++ = 0x00040400; - - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - *cmd++ = pm4_type0_packet(REG_TP0_CHICKEN, 1); - ctx->reg_values[1] = gpuaddr(cmd, &drawctxt->gpustate); - *cmd++ = 0x00000000; - - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - ctx->reg_values[2] = gpuaddr(cmd, &drawctxt->gpustate); - *cmd++ = 0x00000000; - - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE2, 1); - ctx->reg_values[3] = gpuaddr(cmd, &drawctxt->gpustate); - *cmd++ = 0x00000000; - - /* ALU Constants */ - *cmd++ = pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, 3); - *cmd++ = drawctxt->gpustate.gpuaddr & 0xFFFFE000; -#ifdef DISABLE_SHADOW_WRITES - *cmd++ = (0 << 24) | (0 << 16) | 0; /* Disable shadowing */ -#else - *cmd++ = (1 << 24) | (0 << 16) | 0; -#endif - *cmd++ = ALU_CONSTANTS; - - /* Texture Constants */ - *cmd++ = pm4_type3_packet(PM4_LOAD_CONSTANT_CONTEXT, 3); - *cmd++ = (drawctxt->gpustate.gpuaddr + TEX_OFFSET) & 0xFFFFE000; -#ifdef DISABLE_SHADOW_WRITES - /* Disable shadowing */ - *cmd++ = (0 << 24) | (1 << 16) | 0; -#else - *cmd++ = (1 << 24) | (1 << 16) | 0; -#endif - *cmd++ = TEX_CONSTANTS; - - /* Boolean Constants */ - *cmd++ = pm4_type3_packet(PM4_SET_CONSTANT, 1 + BOOL_CONSTANTS); - *cmd++ = (2 << 16) | 0; - - /* the next BOOL_CONSTANT dwords is the shadow area for - * boolean constants. - */ - ctx->bool_shadow = gpuaddr(cmd, &drawctxt->gpustate); - cmd += BOOL_CONSTANTS; - - /* Loop Constants */ - *cmd++ = pm4_type3_packet(PM4_SET_CONSTANT, 1 + LOOP_CONSTANTS); - *cmd++ = (3 << 16) | 0; - - /* the next LOOP_CONSTANTS dwords is the shadow area for - * loop constants. - */ - ctx->loop_shadow = gpuaddr(cmd, &drawctxt->gpustate); - cmd += LOOP_CONSTANTS; - - /* Restore RBBM_PM_OVERRIDE1 */ - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - *cmd++ = pm4_type0_packet(REG_RBBM_PM_OVERRIDE1, 1); - *cmd++ = pm_override1; - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->reg_restore, start, cmd); - - ctx->cmd = cmd; -} - -/* quad for saving/restoring gmem */ -static void set_gmem_copy_quad(struct gmem_shadow_t *shadow) -{ - /* set vertex buffer values */ - gmem_copy_quad[1] = uint2float(shadow->height + shadow->gmem_offset_y); - gmem_copy_quad[3] = uint2float(shadow->width + shadow->gmem_offset_x); - gmem_copy_quad[4] = uint2float(shadow->height + shadow->gmem_offset_y); - gmem_copy_quad[9] = uint2float(shadow->width + shadow->gmem_offset_x); - - gmem_copy_quad[0] = uint2float(shadow->gmem_offset_x); - gmem_copy_quad[6] = uint2float(shadow->gmem_offset_x); - gmem_copy_quad[7] = uint2float(shadow->gmem_offset_y); - gmem_copy_quad[10] = uint2float(shadow->gmem_offset_y); - - BUG_ON(shadow->offset_x); - BUG_ON(shadow->offset_y); - - memcpy(shadow->quad_vertices.hostptr, gmem_copy_quad, QUAD_LEN << 2); - - memcpy(shadow->quad_texcoords.hostptr, gmem_copy_texcoord, - TEXCOORD_LEN << 2); -} - -/* quad for saving/restoring gmem */ -static void build_quad_vtxbuff(struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx, struct gmem_shadow_t *shadow) -{ - unsigned int *cmd = ctx->cmd; - - /* quad vertex buffer location (in GPU space) */ - shadow->quad_vertices.hostptr = cmd; - shadow->quad_vertices.gpuaddr = gpuaddr(cmd, &drawctxt->gpustate); - - cmd += QUAD_LEN; - - /* tex coord buffer location (in GPU space) */ - shadow->quad_texcoords.hostptr = cmd; - shadow->quad_texcoords.gpuaddr = gpuaddr(cmd, &drawctxt->gpustate); - - cmd += TEXCOORD_LEN; - - set_gmem_copy_quad(shadow); - - ctx->cmd = cmd; -} - -static void -build_shader_save_restore_cmds(struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx) -{ - unsigned int *cmd = ctx->cmd; - unsigned int *save, *restore, *fixup; -#if defined(PM4_IM_STORE) - unsigned int *startSizeVtx, *startSizePix, *startSizeShared; -#endif - unsigned int *partition1; - unsigned int *shaderBases, *partition2; - -#if defined(PM4_IM_STORE) - /* compute vertex, pixel and shared instruction shadow GPU addresses */ - ctx->shader_vertex = drawctxt->gpustate.gpuaddr + SHADER_OFFSET; - ctx->shader_pixel = ctx->shader_vertex + SHADER_SHADOW_SIZE; - ctx->shader_shared = ctx->shader_pixel + SHADER_SHADOW_SIZE; -#endif - - /* restore shader partitioning and instructions */ - - restore = cmd; /* start address */ - - /* Invalidate Vertex & Pixel instruction code address and sizes */ - *cmd++ = pm4_type3_packet(PM4_INVALIDATE_STATE, 1); - *cmd++ = 0x00000300; /* 0x100 = Vertex, 0x200 = Pixel */ - - /* Restore previous shader vertex & pixel instruction bases. */ - *cmd++ = pm4_type3_packet(PM4_SET_SHADER_BASES, 1); - shaderBases = cmd++; /* TBD #5: shader bases (from fixup) */ - - /* write the shader partition information to a scratch register */ - *cmd++ = pm4_type0_packet(REG_SQ_INST_STORE_MANAGMENT, 1); - partition1 = cmd++; /* TBD #4a: partition info (from save) */ - -#if defined(PM4_IM_STORE) - /* load vertex shader instructions from the shadow. */ - *cmd++ = pm4_type3_packet(PM4_IM_LOAD, 2); - *cmd++ = ctx->shader_vertex + 0x0; /* 0x0 = Vertex */ - startSizeVtx = cmd++; /* TBD #1: start/size (from save) */ - - /* load pixel shader instructions from the shadow. */ - *cmd++ = pm4_type3_packet(PM4_IM_LOAD, 2); - *cmd++ = ctx->shader_pixel + 0x1; /* 0x1 = Pixel */ - startSizePix = cmd++; /* TBD #2: start/size (from save) */ - - /* load shared shader instructions from the shadow. */ - *cmd++ = pm4_type3_packet(PM4_IM_LOAD, 2); - *cmd++ = ctx->shader_shared + 0x2; /* 0x2 = Shared */ - startSizeShared = cmd++; /* TBD #3: start/size (from save) */ -#endif - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->shader_restore, restore, cmd); - - /* - * fixup SET_SHADER_BASES data - * - * since self-modifying PM4 code is being used here, a seperate - * command buffer is used for this fixup operation, to ensure the - * commands are not read by the PM4 engine before the data fields - * have been written. - */ - - fixup = cmd; /* start address */ - - /* write the shader partition information to a scratch register */ - *cmd++ = pm4_type0_packet(REG_SCRATCH_REG2, 1); - partition2 = cmd++; /* TBD #4b: partition info (from save) */ - - /* mask off unused bits, then OR with shader instruction memory size */ - *cmd++ = pm4_type3_packet(PM4_REG_RMW, 3); - *cmd++ = REG_SCRATCH_REG2; - /* AND off invalid bits. */ - *cmd++ = 0x0FFF0FFF; - /* OR in instruction memory size */ - *cmd++ = (unsigned int)((SHADER_INSTRUCT_LOG2 - 5U) << 29); - - /* write the computed value to the SET_SHADER_BASES data field */ - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_SCRATCH_REG2; - /* TBD #5: shader bases (to restore) */ - *cmd++ = gpuaddr(shaderBases, &drawctxt->gpustate); - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->shader_fixup, fixup, cmd); - - /* save shader partitioning and instructions */ - - save = cmd; /* start address */ - - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - - /* fetch the SQ_INST_STORE_MANAGMENT register value, - * store the value in the data fields of the SET_CONSTANT commands - * above. - */ - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_SQ_INST_STORE_MANAGMENT; - /* TBD #4a: partition info (to restore) */ - *cmd++ = gpuaddr(partition1, &drawctxt->gpustate); - *cmd++ = pm4_type3_packet(PM4_REG_TO_MEM, 2); - *cmd++ = REG_SQ_INST_STORE_MANAGMENT; - /* TBD #4b: partition info (to fixup) */ - *cmd++ = gpuaddr(partition2, &drawctxt->gpustate); - -#if defined(PM4_IM_STORE) - - /* store the vertex shader instructions */ - *cmd++ = pm4_type3_packet(PM4_IM_STORE, 2); - *cmd++ = ctx->shader_vertex + 0x0; /* 0x0 = Vertex */ - /* TBD #1: start/size (to restore) */ - *cmd++ = gpuaddr(startSizeVtx, &drawctxt->gpustate); - - /* store the pixel shader instructions */ - *cmd++ = pm4_type3_packet(PM4_IM_STORE, 2); - *cmd++ = ctx->shader_pixel + 0x1; /* 0x1 = Pixel */ - /* TBD #2: start/size (to restore) */ - *cmd++ = gpuaddr(startSizePix, &drawctxt->gpustate); - - /* store the shared shader instructions if vertex base is nonzero */ - - *cmd++ = pm4_type3_packet(PM4_IM_STORE, 2); - *cmd++ = ctx->shader_shared + 0x2; /* 0x2 = Shared */ - /* TBD #3: start/size (to restore) */ - *cmd++ = gpuaddr(startSizeShared, &drawctxt->gpustate); - -#endif - - *cmd++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmd++ = 0; - - /* create indirect buffer command for above command sequence */ - create_ib1(drawctxt, drawctxt->shader_save, save, cmd); - - ctx->cmd = cmd; -} - -/* create buffers for saving/restoring registers, constants, & GMEM */ -static int -create_gpustate_shadow(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, struct tmp_ctx *ctx) -{ - uint32_t flags; - - flags = (KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN8K); - - /* allocate memory to allow HW to save sub-blocks for efficient context - * save/restore - */ - if (kgsl_sharedmem_alloc(flags, CONTEXT_SIZE, &drawctxt->gpustate) != 0) - return -ENOMEM; - if (kgsl_mmu_map(drawctxt->pagetable, drawctxt->gpustate.physaddr, - drawctxt->gpustate.size, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, - &drawctxt->gpustate.gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN8K)) - return -EINVAL; - - drawctxt->flags |= CTXT_FLAGS_STATE_SHADOW; - - /* Blank out h/w register, constant, and command buffer shadows. */ - kgsl_sharedmem_set(&drawctxt->gpustate, 0, 0, CONTEXT_SIZE); - - /* set-up command and vertex buffer pointers */ - ctx->cmd = ctx->start - = (unsigned int *)((char *)drawctxt->gpustate.hostptr + CMD_OFFSET); - - /* build indirect command buffers to save & restore regs/constants */ - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - build_regrestore_cmds(device, drawctxt, ctx); - build_regsave_cmds(device, drawctxt, ctx); - - build_shader_save_restore_cmds(drawctxt, ctx); - - return 0; -} - -/* create buffers for saving/restoring registers, constants, & GMEM */ -static int -create_gmem_shadow(struct kgsl_device *device, struct kgsl_drawctxt *drawctxt, - struct tmp_ctx *ctx) -{ - unsigned int flags = KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN8K, i; - - config_gmemsize(&drawctxt->context_gmem_shadow, - device->gmemspace.sizebytes); - ctx->gmem_base = device->gmemspace.gpu_base; - - /* allocate memory for GMEM shadow */ - if (kgsl_sharedmem_alloc(flags, drawctxt->context_gmem_shadow.size, - &drawctxt->context_gmem_shadow.gmemshadow) != - 0) - return -ENOMEM; - if (kgsl_mmu_map(drawctxt->pagetable, - drawctxt->context_gmem_shadow.gmemshadow.physaddr, - drawctxt->context_gmem_shadow.gmemshadow.size, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, - &drawctxt->context_gmem_shadow.gmemshadow.gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN8K)) - return -EINVAL; - - /* we've allocated the shadow, when swapped out, GMEM must be saved. */ - drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW | CTXT_FLAGS_GMEM_SAVE; - - /* blank out gmem shadow. */ - kgsl_sharedmem_set(&drawctxt->context_gmem_shadow.gmemshadow, 0, 0, - drawctxt->context_gmem_shadow.size); - - /* build quad vertex buffer */ - build_quad_vtxbuff(drawctxt, ctx, &drawctxt->context_gmem_shadow); - - /* build TP0_CHICKEN register restore command buffer */ - ctx->cmd = build_chicken_restore_cmds(drawctxt, ctx); - - /* build indirect command buffers to save & restore gmem */ - /* Idle because we are reading PM override registers */ - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - drawctxt->context_gmem_shadow.gmem_save_commands = ctx->cmd; - ctx->cmd = - build_gmem2sys_cmds(device, drawctxt, ctx, - &drawctxt->context_gmem_shadow); - drawctxt->context_gmem_shadow.gmem_restore_commands = ctx->cmd; - ctx->cmd = - build_sys2gmem_cmds(device, drawctxt, ctx, - &drawctxt->context_gmem_shadow); - - for (i = 0; i < KGSL_MAX_GMEM_SHADOW_BUFFERS; i++) { - build_quad_vtxbuff(drawctxt, ctx, - &drawctxt->user_gmem_shadow[i]); - - drawctxt->user_gmem_shadow[i].gmem_save_commands = ctx->cmd; - ctx->cmd = - build_gmem2sys_cmds(device, drawctxt, ctx, - &drawctxt->user_gmem_shadow[i]); - - drawctxt->user_gmem_shadow[i].gmem_restore_commands = ctx->cmd; - ctx->cmd = - build_sys2gmem_cmds(device, drawctxt, ctx, - &drawctxt->user_gmem_shadow[i]); - } - - return 0; -} - -/* init draw context */ - -int kgsl_drawctxt_init(struct kgsl_device *device) -{ - return 0; -} - -/* close draw context */ -int kgsl_drawctxt_close(struct kgsl_device *device) -{ - return 0; -} - -/* create a new drawing context */ - -int -kgsl_drawctxt_create(struct kgsl_device *device, - struct kgsl_pagetable *pagetable, - unsigned int flags, unsigned int *drawctxt_id) -{ - struct kgsl_drawctxt *drawctxt; - int index; - struct tmp_ctx ctx; - - KGSL_CTXT_INFO("pt %p flags %08x\n", pagetable, flags); - if (device->drawctxt_count >= KGSL_CONTEXT_MAX) - return -EINVAL; - - /* find a free context slot */ - index = 0; - while (index < KGSL_CONTEXT_MAX) { - if (device->drawctxt[index].flags == CTXT_FLAGS_NOT_IN_USE) - break; - - index++; - } - - if (index >= KGSL_CONTEXT_MAX) - return -EINVAL; - - drawctxt = &device->drawctxt[index]; - drawctxt->pagetable = pagetable; - drawctxt->flags = CTXT_FLAGS_IN_USE; - drawctxt->bin_base_offset = 0; - - device->drawctxt_count++; - - if (create_gpustate_shadow(device, drawctxt, &ctx) - != 0) { - kgsl_drawctxt_destroy(device, index); - return -EINVAL; - } - - /* Save the shader instruction memory on context switching */ - drawctxt->flags |= CTXT_FLAGS_SHADER_SAVE; - - if (!(flags & KGSL_CONTEXT_NO_GMEM_ALLOC)) { - /* create gmem shadow */ - memset(drawctxt->user_gmem_shadow, 0, - sizeof(struct gmem_shadow_t) * - KGSL_MAX_GMEM_SHADOW_BUFFERS); - - if (create_gmem_shadow(device, drawctxt, &ctx) - != 0) { - kgsl_drawctxt_destroy(device, index); - return -EINVAL; - } - } - - BUG_ON(ctx.cmd - ctx.start > CMD_BUFFER_LEN); - - *drawctxt_id = index; - - KGSL_CTXT_INFO("return drawctxt_id %d\n", *drawctxt_id); - return 0; -} - -/* destroy a drawing context */ - -int kgsl_drawctxt_destroy(struct kgsl_device *device, unsigned int drawctxt_id) -{ - struct kgsl_drawctxt *drawctxt; - - drawctxt = &device->drawctxt[drawctxt_id]; - - KGSL_CTXT_INFO("drawctxt_id %d ptr %p\n", drawctxt_id, drawctxt); - if (drawctxt->flags != CTXT_FLAGS_NOT_IN_USE) { - /* deactivate context */ - if (device->drawctxt_active == drawctxt) { - /* no need to save GMEM or shader, the context is - * being destroyed. - */ - drawctxt->flags &= ~(CTXT_FLAGS_GMEM_SAVE | - CTXT_FLAGS_SHADER_SAVE | - CTXT_FLAGS_GMEM_SHADOW | - CTXT_FLAGS_STATE_SHADOW); - - kgsl_drawctxt_switch(device, NULL, 0); - } - - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - - /* destroy state shadow, if allocated */ - if (drawctxt->gpustate.gpuaddr != 0) { - kgsl_mmu_unmap(drawctxt->pagetable, - drawctxt->gpustate.gpuaddr, - drawctxt->gpustate.size); - drawctxt->gpustate.gpuaddr = 0; - } - if (drawctxt->gpustate.physaddr != 0) - kgsl_sharedmem_free(&drawctxt->gpustate); - - /* destroy gmem shadow, if allocated */ - if (drawctxt->context_gmem_shadow.gmemshadow.gpuaddr != 0) { - kgsl_mmu_unmap(drawctxt->pagetable, - drawctxt->context_gmem_shadow.gmemshadow.gpuaddr, - drawctxt->context_gmem_shadow.gmemshadow.size); - drawctxt->context_gmem_shadow.gmemshadow.gpuaddr = 0; - } - - if (drawctxt->context_gmem_shadow.gmemshadow.physaddr != 0) - kgsl_sharedmem_free(&drawctxt->context_gmem_shadow. - gmemshadow); - - drawctxt->flags = CTXT_FLAGS_NOT_IN_USE; - - BUG_ON(device->drawctxt_count == 0); - device->drawctxt_count--; - } - KGSL_CTXT_INFO("return\n"); - return 0; -} - -/* Binds a user specified buffer as GMEM shadow area */ -int kgsl_drawctxt_bind_gmem_shadow(struct kgsl_device *device, - unsigned int drawctxt_id, - const struct kgsl_gmem_desc *gmem_desc, - unsigned int shadow_x, - unsigned int shadow_y, - const struct kgsl_buffer_desc - *shadow_buffer, unsigned int buffer_id) -{ - struct kgsl_drawctxt *drawctxt; - - /* Shadow struct being modified */ - struct gmem_shadow_t *shadow; - unsigned int i; - - if (device->flags & KGSL_FLAGS_SAFEMODE) - /* No need to bind any buffers since safe mode - * skips context switch */ - return 0; - - drawctxt = &device->drawctxt[drawctxt_id]; - - shadow = &drawctxt->user_gmem_shadow[buffer_id]; - - if (!shadow_buffer->enabled) { - /* Disable shadow */ - KGSL_MEM_ERR("shadow is disabled in bind_gmem\n"); - shadow->gmemshadow.size = 0; - } else { - /* Binding to a buffer */ - unsigned int width, height; - - BUG_ON(gmem_desc->x % 2); /* Needs to be a multiple of 2 */ - BUG_ON(gmem_desc->y % 2); /* Needs to be a multiple of 2 */ - BUG_ON(gmem_desc->width % 2); /* Needs to be a multiple of 2 */ - /* Needs to be a multiple of 2 */ - BUG_ON(gmem_desc->height % 2); - /* Needs to be a multiple of 32 */ - BUG_ON(gmem_desc->pitch % 32); - - BUG_ON(shadow_x % 2); /* Needs to be a multiple of 2 */ - BUG_ON(shadow_y % 2); /* Needs to be a multiple of 2 */ - - BUG_ON(shadow_buffer->format < COLORX_4_4_4_4); - BUG_ON(shadow_buffer->format > COLORX_32_32_32_32_FLOAT); - /* Needs to be a multiple of 32 */ - BUG_ON(shadow_buffer->pitch % 32); - - BUG_ON(buffer_id < 0); - BUG_ON(buffer_id > KGSL_MAX_GMEM_SHADOW_BUFFERS); - - width = gmem_desc->width; - height = gmem_desc->height; - - shadow->width = width; - shadow->format = shadow_buffer->format; - - shadow->height = height; - shadow->pitch = shadow_buffer->pitch; - - memset(&shadow->gmemshadow, 0, sizeof(struct kgsl_memdesc)); - shadow->gmemshadow.hostptr = shadow_buffer->hostptr; - shadow->gmemshadow.gpuaddr = shadow_buffer->gpuaddr; - shadow->gmemshadow.physaddr = shadow->gmemshadow.gpuaddr; - shadow->gmemshadow.size = shadow_buffer->size; - - /* Calculate offset */ - shadow->offset = - (int)(shadow_buffer->pitch) * ((int)shadow_y - - (int)gmem_desc->y) + - (int)shadow_x - (int)gmem_desc->x; - - shadow->offset_x = shadow_x; - shadow->offset_y = shadow_y; - shadow->gmem_offset_x = gmem_desc->x; - shadow->gmem_offset_y = gmem_desc->y; - - shadow->size = shadow->gmemshadow.size; - - shadow->gmem_pitch = gmem_desc->pitch; - - /* Modify quad vertices */ - set_gmem_copy_quad(shadow); - - /* Idle because we are reading PM override registers */ - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - - /* Modify commands */ - build_gmem2sys_cmds(device, drawctxt, NULL, shadow); - build_sys2gmem_cmds(device, drawctxt, NULL, shadow); - - /* Release context GMEM shadow if found */ - if (drawctxt->context_gmem_shadow.gmemshadow.physaddr != 0) { - kgsl_sharedmem_free(&drawctxt->context_gmem_shadow. - gmemshadow); - drawctxt->context_gmem_shadow.gmemshadow.physaddr = 0; - } - } - - /* Enable GMEM shadowing if we have any of the user buffers enabled */ - drawctxt->flags &= ~CTXT_FLAGS_GMEM_SHADOW; - for (i = 0; i < KGSL_MAX_GMEM_SHADOW_BUFFERS; i++) { - if (drawctxt->user_gmem_shadow[i].gmemshadow.size > 0) - drawctxt->flags |= CTXT_FLAGS_GMEM_SHADOW; - } - - return 0; -} - -/* set bin base offset */ -int kgsl_drawctxt_set_bin_base_offset(struct kgsl_device *device, - unsigned int drawctxt_id, - unsigned int offset) -{ - struct kgsl_drawctxt *drawctxt; - - drawctxt = &device->drawctxt[drawctxt_id]; - - drawctxt->bin_base_offset = offset; - - return 0; -} - -/* switch drawing contexts */ -void -kgsl_drawctxt_switch(struct kgsl_device *device, struct kgsl_drawctxt *drawctxt, - unsigned int flags) -{ - struct kgsl_drawctxt *active_ctxt = device->drawctxt_active; - unsigned int cmds[2]; - - if (drawctxt) { - /* Set the flag in context so that the save is done - * when this context is switched out. */ - if (flags & KGSL_CONTEXT_SAVE_GMEM) - drawctxt->flags |= CTXT_FLAGS_GMEM_SAVE; - else - drawctxt->flags &= ~CTXT_FLAGS_GMEM_SAVE; - } - /* already current? */ - if (active_ctxt == drawctxt) - return; - - KGSL_CTXT_INFO("from %p to %p flags %d\n", - device->drawctxt_active, drawctxt, flags); - /* save old context*/ - if (active_ctxt != NULL) { - KGSL_CTXT_INFO("active_ctxt flags %08x\n", active_ctxt->flags); - /* save registers and constants. */ - KGSL_CTXT_DBG("save regs"); - kgsl_ringbuffer_issuecmds(device, 0, active_ctxt->reg_save, 3); - - if (active_ctxt->flags & CTXT_FLAGS_SHADER_SAVE) { - /* save shader partitioning and instructions. */ - KGSL_CTXT_DBG("save shader"); - kgsl_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE, - active_ctxt->shader_save, 3); - - /* fixup shader partitioning parameter for - * SET_SHADER_BASES. - */ - KGSL_CTXT_DBG("save shader fixup"); - kgsl_ringbuffer_issuecmds(device, 0, - active_ctxt->shader_fixup, 3); - - active_ctxt->flags |= CTXT_FLAGS_SHADER_RESTORE; - } - - if (active_ctxt->flags & CTXT_FLAGS_GMEM_SAVE - && active_ctxt->flags & CTXT_FLAGS_GMEM_SHADOW) { - /* save gmem. - * (note: changes shader. shader must already be saved.) - */ - unsigned int i, numbuffers = 0; - KGSL_CTXT_DBG("save gmem"); - for (i = 0; i < KGSL_MAX_GMEM_SHADOW_BUFFERS; i++) { - if (active_ctxt->user_gmem_shadow[i].gmemshadow. - size > 0) { - kgsl_ringbuffer_issuecmds(device, - KGSL_CMD_FLAGS_PMODE, - active_ctxt->user_gmem_shadow[i]. - gmem_save, 3); - - /* Restore TP0_CHICKEN */ - kgsl_ringbuffer_issuecmds(device, 0, - active_ctxt->chicken_restore, 3); - - numbuffers++; - } - } - if (numbuffers == 0) { - kgsl_ringbuffer_issuecmds(device, - KGSL_CMD_FLAGS_PMODE, - active_ctxt->context_gmem_shadow.gmem_save, - 3); - - /* Restore TP0_CHICKEN */ - kgsl_ringbuffer_issuecmds(device, 0, - active_ctxt->chicken_restore, 3); - } - - active_ctxt->flags |= CTXT_FLAGS_GMEM_RESTORE; - } - } - - device->drawctxt_active = drawctxt; - - /* restore new context */ - if (drawctxt != NULL) { - - KGSL_CTXT_INFO("drawctxt flags %08x\n", drawctxt->flags); - KGSL_CTXT_DBG("restore pagetable"); - kgsl_mmu_setstate(device, drawctxt->pagetable); - - /* restore gmem. - * (note: changes shader. shader must not already be restored.) - */ - if (drawctxt->flags & CTXT_FLAGS_GMEM_RESTORE) { - unsigned int i, numbuffers = 0; - KGSL_CTXT_DBG("restore gmem"); - - for (i = 0; i < KGSL_MAX_GMEM_SHADOW_BUFFERS; i++) { - if (drawctxt->user_gmem_shadow[i].gmemshadow. - size > 0) { - kgsl_ringbuffer_issuecmds(device, - KGSL_CMD_FLAGS_PMODE, - drawctxt->user_gmem_shadow[i]. - gmem_restore, 3); - - /* Restore TP0_CHICKEN */ - kgsl_ringbuffer_issuecmds(device, 0, - drawctxt->chicken_restore, 3); - numbuffers++; - } - } - if (numbuffers == 0) { - kgsl_ringbuffer_issuecmds(device, - KGSL_CMD_FLAGS_PMODE, - drawctxt->context_gmem_shadow.gmem_restore, - 3); - - /* Restore TP0_CHICKEN */ - kgsl_ringbuffer_issuecmds(device, 0, - drawctxt->chicken_restore, 3); - } - drawctxt->flags &= ~CTXT_FLAGS_GMEM_RESTORE; - } - - /* restore registers and constants. */ - KGSL_CTXT_DBG("restore regs"); - kgsl_ringbuffer_issuecmds(device, 0, - drawctxt->reg_restore, 3); - - /* restore shader instructions & partitioning. */ - if (drawctxt->flags & CTXT_FLAGS_SHADER_RESTORE) - KGSL_CTXT_DBG("restore shader"); - kgsl_ringbuffer_issuecmds(device, 0, - drawctxt->shader_restore, 3); - - cmds[0] = pm4_type3_packet(PM4_SET_BIN_BASE_OFFSET, 1); - cmds[1] = drawctxt->bin_base_offset; - kgsl_ringbuffer_issuecmds(device, 0, cmds, 2); - - } else - kgsl_mmu_setstate(device, device->mmu.defaultpagetable); - KGSL_CTXT_INFO("return\n"); -} diff --git a/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.h b/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.h deleted file mode 100644 index 3090373e..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_drawctxt.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 -* Copyright (c) 2008-2009 QUALCOMM USA, INC. -* -* All source code in this file is licensed under the following license -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* version 2 as published by the Free Software Foundation. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -* See the GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, you can find it at http://www.fsf.org -*/ -#ifndef __GSL_DRAWCTXT_H -#define __GSL_DRAWCTXT_H - -/* Flags */ - -#define CTXT_FLAGS_NOT_IN_USE 0x00000000 -#define CTXT_FLAGS_IN_USE 0x00000001 - -/* state shadow memory allocated */ -#define CTXT_FLAGS_STATE_SHADOW 0x00000010 - -/* gmem shadow memory allocated */ -#define CTXT_FLAGS_GMEM_SHADOW 0x00000100 -/* gmem must be copied to shadow */ -#define CTXT_FLAGS_GMEM_SAVE 0x00000200 -/* gmem can be restored from shadow */ -#define CTXT_FLAGS_GMEM_RESTORE 0x00000400 -/* shader must be copied to shadow */ -#define CTXT_FLAGS_SHADER_SAVE 0x00002000 -/* shader can be restored from shadow */ -#define CTXT_FLAGS_SHADER_RESTORE 0x00004000 - -#include "kgsl_sharedmem.h" -#include "yamato_reg.h" - -#define KGSL_MAX_GMEM_SHADOW_BUFFERS 2 - -struct kgsl_device; - -/* types */ - -/* draw context */ -struct gmem_shadow_t { - struct kgsl_memdesc gmemshadow; /* Shadow buffer address */ - - /* 256 KB GMEM surface = 4 bytes-per-pixel x 256 pixels/row x - * 256 rows. */ - /* width & height must be a multiples of 32, in case tiled textures - * are used. */ - enum COLORFORMATX format; - unsigned int size; /* Size of surface used to store GMEM */ - unsigned int width; /* Width of surface used to store GMEM */ - unsigned int height; /* Height of surface used to store GMEM */ - unsigned int pitch; /* Pitch of surface used to store GMEM */ - int offset; - unsigned int offset_x; - unsigned int offset_y; - unsigned int gmem_offset_x; - unsigned int gmem_offset_y; - unsigned int gmem_pitch; /* Pitch value used for GMEM */ - unsigned int *gmem_save_commands; - unsigned int *gmem_restore_commands; - unsigned int gmem_save[3]; - unsigned int gmem_restore[3]; - struct kgsl_memdesc quad_vertices; - struct kgsl_memdesc quad_texcoords; -}; - -struct kgsl_drawctxt { - uint32_t flags; - struct kgsl_pagetable *pagetable; - struct kgsl_memdesc gpustate; - unsigned int reg_save[3]; - unsigned int reg_restore[3]; - unsigned int shader_save[3]; - unsigned int shader_fixup[3]; - unsigned int shader_restore[3]; - unsigned int chicken_restore[3]; - unsigned int bin_base_offset; - /* Information of the GMEM shadow that is created in context create */ - struct gmem_shadow_t context_gmem_shadow; - /* User defined GMEM shadow buffers */ - struct gmem_shadow_t user_gmem_shadow[KGSL_MAX_GMEM_SHADOW_BUFFERS]; -}; - - -int kgsl_drawctxt_create(struct kgsl_device *, struct kgsl_pagetable *, - unsigned int flags, - unsigned int *drawctxt_id); - -int kgsl_drawctxt_destroy(struct kgsl_device *device, unsigned int drawctxt_id); - -int kgsl_drawctxt_init(struct kgsl_device *device); - -int kgsl_drawctxt_close(struct kgsl_device *device); - -void kgsl_drawctxt_switch(struct kgsl_device *device, - struct kgsl_drawctxt *drawctxt, - unsigned int flags); -int kgsl_drawctxt_bind_gmem_shadow(struct kgsl_device *device, - unsigned int drawctxt_id, - const struct kgsl_gmem_desc *gmem_desc, - unsigned int shadow_x, - unsigned int shadow_y, - const struct kgsl_buffer_desc - *shadow_buffer, unsigned int buffer_id); - -int kgsl_drawctxt_set_bin_base_offset(struct kgsl_device *device, - unsigned int drawctxt_id, - unsigned int offset); - -#endif /* __GSL_DRAWCTXT_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_log.c b/drivers/video/msm/gpu/kgsl/kgsl_log.c deleted file mode 100644 index d39f3447..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_log.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2008 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include "kgsl_log.h" -#include "kgsl_ringbuffer.h" -#include "kgsl_device.h" -#include "kgsl.h" - -/*default log levels is error for everything*/ -#define KGSL_LOG_LEVEL_DEFAULT 3 -#define KGSL_LOG_LEVEL_MAX 7 -unsigned int kgsl_drv_log = KGSL_LOG_LEVEL_DEFAULT; -unsigned int kgsl_cmd_log = KGSL_LOG_LEVEL_DEFAULT; -unsigned int kgsl_ctxt_log = KGSL_LOG_LEVEL_DEFAULT; -unsigned int kgsl_mem_log = KGSL_LOG_LEVEL_DEFAULT; - -unsigned int kgsl_cache_enable; - -#ifdef CONFIG_DEBUG_FS -static int kgsl_log_set(unsigned int *log_val, void *data, u64 val) -{ - *log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX); - return 0; -} - -static int kgsl_drv_log_set(void *data, u64 val) -{ - return kgsl_log_set(&kgsl_drv_log, data, val); -} - -static int kgsl_drv_log_get(void *data, u64 *val) -{ - *val = kgsl_drv_log; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(kgsl_drv_log_fops, kgsl_drv_log_get, - kgsl_drv_log_set, "%llu\n"); - -static int kgsl_cmd_log_set(void *data, u64 val) -{ - return kgsl_log_set(&kgsl_cmd_log, data, val); -} - -static int kgsl_cmd_log_get(void *data, u64 *val) -{ - *val = kgsl_cmd_log; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(kgsl_cmd_log_fops, kgsl_cmd_log_get, - kgsl_cmd_log_set, "%llu\n"); - -static int kgsl_ctxt_log_set(void *data, u64 val) -{ - return kgsl_log_set(&kgsl_ctxt_log, data, val); -} - -static int kgsl_ctxt_log_get(void *data, u64 *val) -{ - *val = kgsl_ctxt_log; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(kgsl_ctxt_log_fops, kgsl_ctxt_log_get, - kgsl_ctxt_log_set, "%llu\n"); - -static int kgsl_mem_log_set(void *data, u64 val) -{ - return kgsl_log_set(&kgsl_mem_log, data, val); -} - -static int kgsl_mem_log_get(void *data, u64 *val) -{ - *val = kgsl_mem_log; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(kgsl_mem_log_fops, kgsl_mem_log_get, - kgsl_mem_log_set, "%llu\n"); - -#ifdef DEBUG -static ssize_t rb_regs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t rb_regs_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct kgsl_device *device = NULL; - struct kgsl_ringbuffer *rb = NULL; - struct kgsl_rb_debug rb_debug; - - device = &kgsl_driver.yamato_device; - - rb = &device->ringbuffer; - - kgsl_ringbuffer_debug(rb, &rb_debug); - - n += scnprintf(buffer + n, debug_bufmax - n, - "rbbm_status %08x mem_rptr %08x mem_wptr_poll %08x\n", - rb_debug.rbbm_status, - rb_debug.mem_rptr, - rb_debug.mem_wptr_poll); - - n += scnprintf(buffer + n, debug_bufmax - n, - "rb_base %08x rb_cntl %08x rb_rptr_addr %08x" - " rb_rptr %08x rb_rptr_wr %08x\n", - rb_debug.cp_rb_base, - rb_debug.cp_rb_cntl, - rb_debug.cp_rb_rptr_addr, - rb_debug.cp_rb_rptr, - rb_debug.cp_rb_rptr_wr); - - n += scnprintf(buffer + n, debug_bufmax - n, - "rb_wptr %08x rb_wptr_delay %08x rb_wptr_base %08x" - " ib1_base %08x ib1_bufsz %08x\n", - rb_debug.cp_rb_wptr, - rb_debug.cp_rb_wptr_delay, - rb_debug.cp_rb_wptr_base, - rb_debug.cp_ib1_base, - rb_debug.cp_ib1_bufsz); - - n += scnprintf(buffer + n, debug_bufmax - n, - "ib2_base %08x ib2_bufsz %08x st_base %08x" - " st_bufsz %08x cp_me_cntl %08x cp_me_status %08x\n", - rb_debug.cp_ib2_base, - rb_debug.cp_ib2_bufsz, - rb_debug.cp_st_base, - rb_debug.cp_st_bufsz, - rb_debug.cp_me_cntl, - rb_debug.cp_me_status); - - n += scnprintf(buffer + n, debug_bufmax - n, - "csq_cp_rb %08x csq_cp_ib1 %08x csq_cp_ib2 %08x\n", - rb_debug.cp_csq_rb_stat, - rb_debug.cp_csq_ib1_stat, - rb_debug.cp_csq_ib2_stat); - - n += scnprintf(buffer + n, debug_bufmax - n, - "cp_debug %08x cp_stat %08x cp_int_status %08x" - " cp_int_cntl %08x\n", - rb_debug.cp_debug, - rb_debug.cp_stat, - rb_debug.cp_int_status, - rb_debug.cp_int_cntl); - - n += scnprintf(buffer + n, debug_bufmax - n, - "sop_timestamp: %0d eop_timestamp: %d\n", - rb_debug.sop_timestamp, - rb_debug.eop_timestamp); - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static struct file_operations kgsl_rb_regs_fops = { - .read = rb_regs_read, - .open = rb_regs_open, -}; -#endif /*DEBUG*/ - -#ifdef DEBUG -static ssize_t mmu_regs_open(struct inode *inode, struct file *file) -{ - file->private_data = inode->i_private; - return 0; -} - -static ssize_t mmu_regs_read(struct file *file, char __user *buf, size_t count, - loff_t *ppos) -{ - const int debug_bufmax = 4096; - static char buffer[4096]; - int n = 0; - struct kgsl_device *device = NULL; - struct kgsl_mmu *mmu = NULL; - struct kgsl_mmu_debug mmu_debug; - - device = &kgsl_driver.yamato_device; - - mmu = &device->mmu; - - kgsl_mmu_debug(mmu, &mmu_debug); - - n += scnprintf(buffer + n, debug_bufmax - n, - "config %08x mpu_base %08x mpu_end %08x\n", - mmu_debug.config, - mmu_debug.mpu_base, - mmu_debug.mpu_end); - - n += scnprintf(buffer + n, debug_bufmax - n, - "va_range %08x pt_base %08x\n", - mmu_debug.va_range, - mmu_debug.pt_base); - - n += scnprintf(buffer + n, debug_bufmax - n, - "page_fault %08x trans_error %08x axi_error %08x\n", - mmu_debug.page_fault, - mmu_debug.trans_error, - mmu_debug.axi_error); - - n += scnprintf(buffer + n, debug_bufmax - n, - "interrupt_mask %08x interrupt_status %08x\n", - mmu_debug.interrupt_mask, - mmu_debug.interrupt_status); - - n++; - buffer[n] = 0; - return simple_read_from_buffer(buf, count, ppos, buffer, n); -} - -static struct file_operations kgsl_mmu_regs_fops = { - .read = mmu_regs_read, - .open = mmu_regs_open, -}; -#endif /*DEBUG*/ - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -static int kgsl_cache_enable_set(void *data, u64 val) -{ - kgsl_cache_enable = (val != 0); - return 0; -} - -static int kgsl_cache_enable_get(void *data, u64 *val) -{ - *val = kgsl_cache_enable; - return 0; -} - -DEFINE_SIMPLE_ATTRIBUTE(kgsl_cache_enable_fops, kgsl_cache_enable_get, - kgsl_cache_enable_set, "%llu\n"); -#endif - -#endif /* CONFIG_DEBUG_FS */ - -int kgsl_debug_init(void) -{ -#ifdef CONFIG_DEBUG_FS - struct dentry *dent; - dent = debugfs_create_dir("kgsl", 0); - if (IS_ERR(dent)) - return 0; - - debugfs_create_file("log_level_cmd", 0644, dent, 0, - &kgsl_cmd_log_fops); - debugfs_create_file("log_level_ctxt", 0644, dent, 0, - &kgsl_ctxt_log_fops); - debugfs_create_file("log_level_drv", 0644, dent, 0, - &kgsl_drv_log_fops); - debugfs_create_file("log_level_mem", 0644, dent, 0, - &kgsl_mem_log_fops); -#ifdef DEBUG - debugfs_create_file("rb_regs", 0444, dent, 0, - &kgsl_rb_regs_fops); -#endif - -#ifdef DEBUG - debugfs_create_file("mmu_regs", 0444, dent, 0, - &kgsl_mmu_regs_fops); -#endif - -#ifdef CONFIG_GPU_MSM_KGSL_MMU - debugfs_create_file("cache_enable", 0644, dent, 0, - &kgsl_cache_enable_fops); -#endif - -#endif /* CONFIG_DEBUG_FS */ - return 0; -} diff --git a/drivers/video/msm/gpu/kgsl/kgsl_log.h b/drivers/video/msm/gpu/kgsl/kgsl_log.h deleted file mode 100644 index 3869ff74..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_log.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2008 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef _GSL_LOG_H -#define _GSL_LOG_H - -#include -#include -#include -#include - -extern unsigned int kgsl_drv_log; -extern unsigned int kgsl_cmd_log; -extern unsigned int kgsl_ctxt_log; -extern unsigned int kgsl_mem_log; - -struct device *kgsl_driver_getdevnode(void); -int kgsl_debug_init(void); - -#define KGSL_LOG_VDBG(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 7) \ - dev_vdbg(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_LOG_DBG(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 7) \ - dev_dbg(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_LOG_INFO(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 6) \ - dev_info(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_LOG_WARN(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 4) \ - dev_warn(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_LOG_ERR(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 3) \ - dev_err(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_LOG_FATAL(lvl, fmt, args...) \ - do { \ - if ((lvl) >= 2) \ - dev_crit(kgsl_driver_getdevnode(), "|%s| " fmt, \ - __func__, ##args);\ - } while (0) - -#define KGSL_DRV_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_drv_log, fmt, ##args) -#define KGSL_DRV_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_drv_log, fmt, ##args) -#define KGSL_DRV_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_drv_log, fmt, ##args) -#define KGSL_DRV_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_drv_log, fmt, ##args) -#define KGSL_DRV_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_drv_log, fmt, ##args) -#define KGSL_DRV_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_drv_log, fmt, ##args) - -#define KGSL_CMD_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_cmd_log, fmt, ##args) -#define KGSL_CMD_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_cmd_log, fmt, ##args) -#define KGSL_CMD_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_cmd_log, fmt, ##args) -#define KGSL_CMD_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_cmd_log, fmt, ##args) -#define KGSL_CMD_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_cmd_log, fmt, ##args) -#define KGSL_CMD_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_cmd_log, fmt, ##args) - -#define KGSL_CTXT_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_ctxt_log, fmt, ##args) -#define KGSL_CTXT_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_ctxt_log, fmt, ##args) -#define KGSL_CTXT_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_ctxt_log, fmt, ##args) -#define KGSL_CTXT_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_ctxt_log, fmt, ##args) -#define KGSL_CTXT_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_ctxt_log, fmt, ##args) -#define KGSL_CTXT_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_ctxt_log, fmt, ##args) - -#define KGSL_MEM_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_mem_log, fmt, ##args) -#define KGSL_MEM_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_mem_log, fmt, ##args) -#define KGSL_MEM_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_mem_log, fmt, ##args) -#define KGSL_MEM_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_mem_log, fmt, ##args) -#define KGSL_MEM_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_mem_log, fmt, ##args) -#define KGSL_MEM_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_mem_log, fmt, ##args) - -#endif /* _GSL_LOG_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_mmu.c b/drivers/video/msm/gpu/kgsl/kgsl_mmu.c deleted file mode 100644 index eb7794ba..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_mmu.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include -#include -#include - -#include -#include - -#include "kgsl_mmu.h" -#include "kgsl.h" -#include "kgsl_log.h" -#include "yamato_reg.h" - -struct kgsl_pte_debug { - unsigned int read:1; - unsigned int write:1; - unsigned int dirty:1; - unsigned int reserved:9; - unsigned int phyaddr:20; -}; - -#define GSL_PTE_SIZE 4 -#define GSL_PT_EXTRA_ENTRIES 16 - - -#define GSL_PT_PAGE_BITS_MASK 0x00000007 -#define GSL_PT_PAGE_ADDR_MASK (~(KGSL_PAGESIZE - 1)) - -#define GSL_MMU_INT_MASK \ - (MH_INTERRUPT_MASK__AXI_READ_ERROR | \ - MH_INTERRUPT_MASK__AXI_WRITE_ERROR) - -uint32_t kgsl_pt_entry_get(struct kgsl_pagetable *pt, uint32_t va) -{ - return (va - pt->va_base) >> KGSL_PAGESIZE_SHIFT; -} - -uint32_t kgsl_pt_map_get(struct kgsl_pagetable *pt, uint32_t pte) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - return baseptr[pte]; -} - -void kgsl_pt_map_set(struct kgsl_pagetable *pt, uint32_t pte, uint32_t val) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - baseptr[pte] = val; -} -#define GSL_PT_MAP_DEBUG(pte) ((struct kgsl_pte_debug *) \ - &gsl_pt_map_get(pagetable, pte)) - -void kgsl_pt_map_setbits(struct kgsl_pagetable *pt, uint32_t pte, uint32_t bits) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - baseptr[pte] |= bits; -} - -void kgsl_pt_map_setaddr(struct kgsl_pagetable *pt, uint32_t pte, - uint32_t pageaddr) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - uint32_t val = baseptr[pte]; - val &= ~GSL_PT_PAGE_ADDR_MASK; - val |= (pageaddr & GSL_PT_PAGE_ADDR_MASK); - baseptr[pte] = val; -} - -void kgsl_pt_map_resetall(struct kgsl_pagetable *pt, uint32_t pte) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - baseptr[pte] &= GSL_PT_PAGE_DIRTY; -} - -void kgsl_pt_map_resetbits(struct kgsl_pagetable *pt, uint32_t pte, - uint32_t bits) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - baseptr[pte] &= ~(bits & GSL_PT_PAGE_BITS_MASK); -} - -int kgsl_pt_map_isdirty(struct kgsl_pagetable *pt, uint32_t pte) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - return baseptr[pte] & GSL_PT_PAGE_DIRTY; -} - -uint32_t kgsl_pt_map_getaddr(struct kgsl_pagetable *pt, uint32_t pte) -{ - uint32_t *baseptr = (uint32_t *)pt->base.hostptr; - return baseptr[pte] & GSL_PT_PAGE_ADDR_MASK; -} - -void kgsl_mh_intrcallback(struct kgsl_device *device) -{ - unsigned int status = 0; - unsigned int reg; - unsigned int axi_error; - struct kgsl_mmu_debug dbg; - - KGSL_MEM_VDBG("enter (device=%p)\n", device); - - kgsl_yamato_regread(device, REG_MH_INTERRUPT_STATUS, &status); - - if (status & MH_INTERRUPT_MASK__AXI_READ_ERROR) { - kgsl_yamato_regread(device, REG_MH_AXI_ERROR, &axi_error); - KGSL_MEM_FATAL("axi read error interrupt (%08x)\n", axi_error); - kgsl_mmu_debug(&device->mmu, &dbg); - } else if (status & MH_INTERRUPT_MASK__AXI_WRITE_ERROR) { - kgsl_yamato_regread(device, REG_MH_AXI_ERROR, &axi_error); - KGSL_MEM_FATAL("axi write error interrupt (%08x)\n", axi_error); - kgsl_mmu_debug(&device->mmu, &dbg); - } else if (status & MH_INTERRUPT_MASK__MMU_PAGE_FAULT) { - kgsl_yamato_regread(device, REG_MH_MMU_PAGE_FAULT, ®); - KGSL_MEM_FATAL("mmu page fault interrupt: %08x\n", reg); - kgsl_mmu_debug(&device->mmu, &dbg); - } else { - KGSL_MEM_DBG("bad bits in REG_MH_INTERRUPT_STATUS %08x\n", - status); - } - - kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_CLEAR, status); - - /*TODO: figure out how to handle errror interupts. - * specifically, page faults should probably nuke the client that - * caused them, but we don't have enough info to figure that out yet. - */ - - KGSL_MEM_VDBG("return\n"); -} - -#ifdef DEBUG -void kgsl_mmu_debug(struct kgsl_mmu *mmu, struct kgsl_mmu_debug *regs) -{ - memset(regs, 0, sizeof(struct kgsl_mmu_debug)); - - kgsl_yamato_regread(mmu->device, REG_MH_MMU_CONFIG, - ®s->config); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_MPU_BASE, - ®s->mpu_base); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_MPU_END, - ®s->mpu_end); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_VA_RANGE, - ®s->va_range); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_PT_BASE, - ®s->pt_base); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_PAGE_FAULT, - ®s->page_fault); - kgsl_yamato_regread(mmu->device, REG_MH_MMU_TRAN_ERROR, - ®s->trans_error); - kgsl_yamato_regread(mmu->device, REG_MH_AXI_ERROR, - ®s->axi_error); - kgsl_yamato_regread(mmu->device, REG_MH_INTERRUPT_MASK, - ®s->interrupt_mask); - kgsl_yamato_regread(mmu->device, REG_MH_INTERRUPT_STATUS, - ®s->interrupt_status); - - KGSL_MEM_DBG("mmu config %08x mpu_base %08x mpu_end %08x\n", - regs->config, regs->mpu_base, regs->mpu_end); - KGSL_MEM_DBG("mmu va_range %08x pt_base %08x \n", - regs->va_range, regs->pt_base); - KGSL_MEM_DBG("mmu page_fault %08x tran_err %08x\n", - regs->page_fault, regs->trans_error); - KGSL_MEM_DBG("mmu int mask %08x int status %08x\n", - regs->interrupt_mask, regs->interrupt_status); -} -#endif - -struct kgsl_pagetable *kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu) -{ - int status = 0; - struct kgsl_pagetable *pagetable = NULL; - uint32_t flags; - - KGSL_MEM_VDBG("enter (mmu=%p)\n", mmu); - - pagetable = kzalloc(sizeof(struct kgsl_pagetable), GFP_KERNEL); - if (pagetable == NULL) { - KGSL_MEM_ERR("Unable to allocate pagetable object.\n"); - return NULL; - } - - pagetable->mmu = mmu; - pagetable->va_base = mmu->va_base; - pagetable->va_range = mmu->va_range; - pagetable->last_superpte = 0; - pagetable->max_entries = (mmu->va_range >> KGSL_PAGESIZE_SHIFT) - + GSL_PT_EXTRA_ENTRIES; - - pagetable->pool = gen_pool_create(KGSL_PAGESIZE_SHIFT, -1); - if (pagetable->pool == NULL) { - KGSL_MEM_ERR("Unable to allocate virtualaddr pool.\n"); - goto err_gen_pool_create; - } - - if (gen_pool_add(pagetable->pool, pagetable->va_base, - pagetable->va_range, -1)) { - KGSL_MEM_ERR("gen_pool_create failed for pagetable %p\n", - pagetable); - goto err_gen_pool_add; - } - - /* allocate page table memory */ - flags = (KGSL_MEMFLAGS_ALIGN4K | KGSL_MEMFLAGS_CONPHYS - | KGSL_MEMFLAGS_STRICTREQUEST); - status = kgsl_sharedmem_alloc(flags, - pagetable->max_entries * GSL_PTE_SIZE, - &pagetable->base); - - if (status) { - KGSL_MEM_ERR("cannot alloc page tables\n"); - goto err_kgsl_sharedmem_alloc; - } - - /* reset page table entries - * -- all pte's are marked as not dirty initially - */ - kgsl_sharedmem_set(&pagetable->base, 0, 0, pagetable->base.size); - pagetable->base.gpuaddr = pagetable->base.physaddr; - - KGSL_MEM_VDBG("return %p\n", pagetable); - - return pagetable; - -err_kgsl_sharedmem_alloc: -err_gen_pool_add: - gen_pool_destroy(pagetable->pool); -err_gen_pool_create: - kfree(pagetable); - return NULL; -} - -int kgsl_mmu_destroypagetableobject(struct kgsl_pagetable *pagetable) -{ - KGSL_MEM_VDBG("enter (pagetable=%p)\n", pagetable); - - if (pagetable) { - if (pagetable->base.gpuaddr) - kgsl_sharedmem_free(&pagetable->base); - - if (pagetable->pool) { - gen_pool_destroy(pagetable->pool); - pagetable->pool = NULL; - } - - kfree(pagetable); - - } - KGSL_MEM_VDBG("return 0x%08x\n", 0); - - return 0; -} - -int kgsl_mmu_setstate(struct kgsl_device *device, - struct kgsl_pagetable *pagetable) -{ - int status = 0; - struct kgsl_mmu *mmu = &device->mmu; - - KGSL_MEM_VDBG("enter (device=%p, pagetable=%p)\n", device, pagetable); - - if (mmu->flags & KGSL_FLAGS_STARTED) { - /* page table not current, then setup mmu to use new - * specified page table - */ - KGSL_MEM_INFO("from %p to %p\n", mmu->hwpagetable, pagetable); - if (mmu->hwpagetable != pagetable) { - mmu->hwpagetable = pagetable; - - /* call device specific set page table */ - status = kgsl_yamato_setstate(mmu->device, - KGSL_MMUFLAGS_TLBFLUSH | - KGSL_MMUFLAGS_PTUPDATE); - } - } - - KGSL_MEM_VDBG("return %d\n", status); - - return status; -} - -int kgsl_mmu_init(struct kgsl_device *device) -{ - /* - * intialize device mmu - * - * call this with the global lock held - */ - int status; - uint32_t flags; - struct kgsl_mmu *mmu = &device->mmu; -#ifdef _DEBUG - struct kgsl_mmu_debug regs; -#endif /* _DEBUG */ - - KGSL_MEM_VDBG("enter (device=%p)\n", device); - - if (mmu->flags & KGSL_FLAGS_INITIALIZED0) { - KGSL_MEM_INFO("MMU already initialized.\n"); - return 0; - } - - mmu->device = device; - -#ifndef CONFIG_GPU_MSM_KGSL_MMU - mmu->config = 0x00000000; -#endif - - /* setup MMU and sub-client behavior */ - kgsl_yamato_regwrite(device, REG_MH_MMU_CONFIG, mmu->config); - - /* enable axi interrupts */ - KGSL_MEM_DBG("enabling mmu interrupts mask=0x%08lx\n", - GSL_MMU_INT_MASK); - kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK, GSL_MMU_INT_MASK); - - mmu->flags |= KGSL_FLAGS_INITIALIZED0; - - /* MMU not enabled */ - if ((mmu->config & 0x1) == 0) { - KGSL_MEM_VDBG("return %d\n", 0); - return 0; - } - - /* idle device */ - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - - /* make sure aligned to pagesize */ - BUG_ON(mmu->mpu_base & (KGSL_PAGESIZE - 1)); - BUG_ON((mmu->mpu_base + mmu->mpu_range) & (KGSL_PAGESIZE - 1)); - - /* define physical memory range accessible by the core */ - kgsl_yamato_regwrite(device, REG_MH_MMU_MPU_BASE, - mmu->mpu_base); - kgsl_yamato_regwrite(device, REG_MH_MMU_MPU_END, - mmu->mpu_base + mmu->mpu_range); - - /* enable axi interrupts */ - KGSL_MEM_DBG("enabling mmu interrupts mask=0x%08lx\n", - GSL_MMU_INT_MASK | MH_INTERRUPT_MASK__MMU_PAGE_FAULT); - kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK, - GSL_MMU_INT_MASK | MH_INTERRUPT_MASK__MMU_PAGE_FAULT); - - mmu->flags |= KGSL_FLAGS_INITIALIZED; - - /* sub-client MMU lookups require address translation */ - if ((mmu->config & ~0x1) > 0) { - /*make sure virtual address range is a multiple of 64Kb */ - BUG_ON(mmu->va_range & ((1 << 16) - 1)); - - /* allocate memory used for completing r/w operations that - * cannot be mapped by the MMU - */ - flags = (KGSL_MEMFLAGS_ALIGN4K | KGSL_MEMFLAGS_CONPHYS - | KGSL_MEMFLAGS_STRICTREQUEST); - status = kgsl_sharedmem_alloc(flags, 64, &mmu->dummyspace); - if (status != 0) { - KGSL_MEM_ERR - ("Unable to allocate dummy space memory.\n"); - kgsl_mmu_close(device); - return status; - } - - kgsl_sharedmem_set(&mmu->dummyspace, 0, 0, - mmu->dummyspace.size); - /* TRAN_ERROR needs a 32 byte (32 byte aligned) chunk of memory - * to complete transactions in case of an MMU fault. Note that - * we'll leave the bottom 32 bytes of the dummyspace for other - * purposes (e.g. use it when dummy read cycles are needed - * for other blocks */ - kgsl_yamato_regwrite(device, - REG_MH_MMU_TRAN_ERROR, - mmu->dummyspace.physaddr + 32); - - mmu->defaultpagetable = kgsl_mmu_createpagetableobject(mmu); - if (!mmu->defaultpagetable) { - KGSL_MEM_ERR("Failed to create global page table\n"); - kgsl_mmu_close(device); - return -ENOMEM; - } - mmu->hwpagetable = mmu->defaultpagetable; - mmu->tlbflushfilter.size = (mmu->va_range / - (PAGE_SIZE * GSL_PT_SUPER_PTE * 8)) + 1; - mmu->tlbflushfilter.base = (unsigned int *) - kzalloc(mmu->tlbflushfilter.size, GFP_KERNEL); - if (!mmu->tlbflushfilter.base) { - KGSL_MEM_ERR("Failed to create tlbflushfilter\n"); - kgsl_mmu_close(device); - return -ENOMEM; - } - GSL_TLBFLUSH_FILTER_RESET(); - kgsl_yamato_regwrite(device, REG_MH_MMU_PT_BASE, - mmu->hwpagetable->base.gpuaddr); - kgsl_yamato_regwrite(device, REG_MH_MMU_VA_RANGE, - (mmu->hwpagetable->va_base | - (mmu->hwpagetable->va_range >> 16))); - status = kgsl_yamato_setstate(device, KGSL_MMUFLAGS_TLBFLUSH); - if (status) { - kgsl_mmu_close(device); - return status; - } - - mmu->flags |= KGSL_FLAGS_STARTED; - } - - KGSL_MEM_VDBG("return %d\n", 0); - - return 0; -} - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr) -{ - pgd_t *pgd_ptr = NULL; - pmd_t *pmd_ptr = NULL; - pte_t *pte_ptr = NULL; - - pgd_ptr = pgd_offset(current->mm, vaddr); - if (pgd_none(*pgd) || pgd_bad(*pgd)) { - KGSL_MEM_ERR - ("Invalid pgd entry found while trying to convert virtual " - "address to physical\n"); - return 0; - } - - pmd_ptr = pmd_offset(pgd_ptr, vaddr); - if (pmd_none(*pmd_ptr) || pmd_bad(*pmd_ptr)) { - KGSL_MEM_ERR - ("Invalid pmd entry found while trying to convert virtual " - "address to physical\n"); - return 0; - } - - pte_ptr = pte_offset_map(pmd_ptr, vaddr); - if (!pte_ptr) { - KGSL_MEM_ERR - ("Unable to map pte entry while trying to convert virtual " - "address to physical\n"); - return 0; - } - return pte_ptr; -} - -int kgsl_mmu_map(struct kgsl_pagetable *pagetable, - unsigned int address, - int range, - unsigned int protflags, - unsigned int *gpuaddr, - unsigned int flags) -{ - int numpages; - unsigned int pte, ptefirst, ptelast, physaddr; - int flushtlb, alloc_size; - struct kgsl_mmu *mmu = NULL; - int phys_contiguous = flags & KGSL_MEMFLAGS_CONPHYS; - unsigned int align = flags & KGSL_MEMFLAGS_ALIGN_MASK; - - KGSL_MEM_VDBG("enter (pt=%p, physaddr=%08x, range=%08d, gpuaddr=%p)\n", - pagetable, address, range, gpuaddr); - - mmu = pagetable->mmu; - - BUG_ON(mmu == NULL); - BUG_ON(protflags & ~(GSL_PT_PAGE_RV | GSL_PT_PAGE_WV)); - BUG_ON(protflags == 0); - BUG_ON(range <= 0); - - /* Only support 4K and 8K alignment for now */ - if (align != KGSL_MEMFLAGS_ALIGN8K && align != KGSL_MEMFLAGS_ALIGN4K) { - KGSL_MEM_ERR("Cannot map memory according to " - "requested flags: %08x\n", flags); - return -EINVAL; - } - - /* Make sure address being mapped is at 4K boundary */ - if (!IS_ALIGNED(address, KGSL_PAGESIZE) || range & ~KGSL_PAGEMASK) { - KGSL_MEM_ERR("Cannot map address not aligned " - "at page boundary: address: %08x, range: %08x\n", - address, range); - return -EINVAL; - } - alloc_size = range; - if (align == KGSL_MEMFLAGS_ALIGN8K) - alloc_size += KGSL_PAGESIZE; - - *gpuaddr = gen_pool_alloc(pagetable->pool, alloc_size); - if (*gpuaddr == 0) { - KGSL_MEM_ERR("gen_pool_alloc failed: %d\n", alloc_size); - return -ENOMEM; - } - - if (align == KGSL_MEMFLAGS_ALIGN8K) { - if (*gpuaddr & ((1 << 13) - 1)) { - /* Not 8k aligned, align it */ - gen_pool_free(pagetable->pool, *gpuaddr, KGSL_PAGESIZE); - *gpuaddr = *gpuaddr + KGSL_PAGESIZE; - } else - gen_pool_free(pagetable->pool, *gpuaddr + range, - KGSL_PAGESIZE); - } - - numpages = (range >> KGSL_PAGESIZE_SHIFT); - - ptefirst = kgsl_pt_entry_get(pagetable, *gpuaddr); - ptelast = ptefirst + numpages; - - pte = ptefirst; - flushtlb = 0; - - /* tlb needs to be flushed when the first and last pte are not at - * superpte boundaries */ - if ((ptefirst & (GSL_PT_SUPER_PTE - 1)) != 0 || - ((ptelast + 1) & (GSL_PT_SUPER_PTE-1)) != 0) - flushtlb = 1; - - for (pte = ptefirst; pte < ptelast; pte++) { -#ifdef VERBOSE_DEBUG - /* check if PTE exists */ - uint32_t val = kgsl_pt_map_getaddr(pagetable, pte); - BUG_ON(val != 0 && val != GSL_PT_PAGE_DIRTY); -#endif - if ((pte & (GSL_PT_SUPER_PTE-1)) == 0) - if (GSL_TLBFLUSH_FILTER_ISDIRTY(pte / GSL_PT_SUPER_PTE)) - flushtlb = 1; - - /* mark pte as in use */ - if (phys_contiguous) - physaddr = address; - else { - physaddr = vmalloc_to_pfn((void *)address); - physaddr <<= PAGE_SHIFT; - } - - if (physaddr) - kgsl_pt_map_set(pagetable, pte, physaddr | protflags); - else { - KGSL_MEM_ERR - ("Unable to find physaddr for vmallloc address: %x\n", - address); - kgsl_mmu_unmap(pagetable, *gpuaddr, range); - return -EFAULT; - } - address += KGSL_PAGESIZE; - } - - KGSL_MEM_INFO("pt %p p %08x g %08x pte f %d l %d n %d f %d\n", - pagetable, address, *gpuaddr, ptefirst, ptelast, - numpages, flushtlb); - - dmb(); - - /* Invalidate tlb only if current page table used by GPU is the - * pagetable that we used to allocate */ - if (flushtlb && (pagetable == mmu->hwpagetable)) { - kgsl_yamato_setstate(mmu->device, KGSL_MMUFLAGS_TLBFLUSH); - GSL_TLBFLUSH_FILTER_RESET(); - } - - - KGSL_MEM_VDBG("return %d\n", 0); - - return 0; -} - -int -kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, unsigned int gpuaddr, - int range) -{ - unsigned int numpages; - unsigned int pte, ptefirst, ptelast, superpte; - struct kgsl_mmu *mmu = NULL; - - KGSL_MEM_VDBG("enter (pt=%p, gpuaddr=0x%08x, range=%d)\n", - pagetable, gpuaddr, range); - - BUG_ON(range <= 0); - - numpages = (range >> KGSL_PAGESIZE_SHIFT); - if (range & (KGSL_PAGESIZE - 1)) - numpages++; - - ptefirst = kgsl_pt_entry_get(pagetable, gpuaddr); - ptelast = ptefirst + numpages; - - KGSL_MEM_INFO("pt %p gpu %08x pte first %d last %d numpages %d\n", - pagetable, gpuaddr, ptefirst, ptelast, numpages); - - mmu = pagetable->mmu; - - superpte = ptefirst - (ptefirst & (GSL_PT_SUPER_PTE-1)); - GSL_TLBFLUSH_FILTER_SETDIRTY(superpte / GSL_PT_SUPER_PTE); - for (pte = ptefirst; pte < ptelast; pte++) { -#ifdef VERBOSE_DEBUG - /* check if PTE exists */ - BUG_ON(!kgsl_pt_map_getaddr(pagetable, pte)); -#endif - kgsl_pt_map_set(pagetable, pte, GSL_PT_PAGE_DIRTY); - superpte = pte - (pte & (GSL_PT_SUPER_PTE - 1)); - if (pte == superpte) - GSL_TLBFLUSH_FILTER_SETDIRTY(superpte / - GSL_PT_SUPER_PTE); - } - - dmb(); - - gen_pool_free(pagetable->pool, gpuaddr, range); - - KGSL_MEM_VDBG("return %d\n", 0); - - return 0; -} -#endif - -int kgsl_mmu_close(struct kgsl_device *device) -{ - /* - * close device mmu - * - * call this with the global lock held - */ - struct kgsl_mmu *mmu = &device->mmu; -#ifdef _DEBUG - int i; -#endif /* _DEBUG */ - - KGSL_MEM_VDBG("enter (device=%p)\n", device); - - if (mmu->flags & KGSL_FLAGS_INITIALIZED0) { - /* disable mh interrupts */ - KGSL_MEM_DBG("disabling mmu interrupts\n"); - kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK, 0); - - /* disable MMU */ - kgsl_yamato_regwrite(device, REG_MH_MMU_CONFIG, 0x00000000); - - if (mmu->dummyspace.gpuaddr) - kgsl_sharedmem_free(&mmu->dummyspace); - - if (mmu->tlbflushfilter.base) { - mmu->tlbflushfilter.size = 0; - kfree(mmu->tlbflushfilter.base); - mmu->tlbflushfilter.base = NULL; - } - - mmu->flags &= ~KGSL_FLAGS_STARTED; - mmu->flags &= ~KGSL_FLAGS_INITIALIZED; - mmu->flags &= ~KGSL_FLAGS_INITIALIZED0; - kgsl_mmu_destroypagetableobject(mmu->defaultpagetable); - mmu->defaultpagetable = NULL; - } - - KGSL_MEM_VDBG("return %d\n", 0); - - return 0; -} diff --git a/drivers/video/msm/gpu/kgsl/kgsl_mmu.h b/drivers/video/msm/gpu/kgsl/kgsl_mmu.h deleted file mode 100644 index 627a6b82..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_mmu.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef __GSL_MMU_H -#define __GSL_MMU_H -#include -#include -#include "kgsl_log.h" -#include "kgsl_sharedmem.h" - -#define GSL_PT_SUPER_PTE 8 -#define GSL_PT_PAGE_WV 0x00000001 -#define GSL_PT_PAGE_RV 0x00000002 -#define GSL_PT_PAGE_DIRTY 0x00000004 -/* MMU Flags */ -#define KGSL_MMUFLAGS_TLBFLUSH 0x10000000 -#define KGSL_MMUFLAGS_PTUPDATE 0x20000000 - -/* Macros to manage TLB flushing */ -#define GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS (sizeof(unsigned char) * 8) -#define GSL_TLBFLUSH_FILTER_GET(superpte) \ - (*((unsigned char *) \ - (((unsigned int)mmu->tlbflushfilter.base) \ - + (superpte / GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS)))) -#define GSL_TLBFLUSH_FILTER_SETDIRTY(superpte) \ - (GSL_TLBFLUSH_FILTER_GET((superpte)) |= 1 << \ - (superpte % GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS)) -#define GSL_TLBFLUSH_FILTER_ISDIRTY(superpte) \ - (GSL_TLBFLUSH_FILTER_GET((superpte)) & \ - (1 << (superpte % GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS))) -#define GSL_TLBFLUSH_FILTER_RESET() memset(mmu->tlbflushfilter.base,\ - 0, mmu->tlbflushfilter.size) - -extern unsigned int kgsl_cache_enable; - -struct kgsl_device; - -struct kgsl_mmu_debug { - unsigned int config; - unsigned int mpu_base; - unsigned int mpu_end; - unsigned int va_range; - unsigned int pt_base; - unsigned int page_fault; - unsigned int trans_error; - unsigned int axi_error; - unsigned int interrupt_mask; - unsigned int interrupt_status; -}; - -struct kgsl_ptstats { - int64_t maps; - int64_t unmaps; - int64_t superpteallocs; - int64_t superptefrees; - int64_t ptswitches; - int64_t tlbflushes[KGSL_DEVICE_MAX]; -}; - -struct kgsl_pagetable { - unsigned int refcnt; - struct kgsl_mmu *mmu; - struct kgsl_memdesc base; - uint32_t va_base; - unsigned int va_range; - unsigned int last_superpte; - unsigned int max_entries; - struct gen_pool *pool; -}; - -struct kgsl_tlbflushfilter { - unsigned int *base; - unsigned int size; -}; - -struct kgsl_mmu { - unsigned int refcnt; - uint32_t flags; - struct kgsl_device *device; - unsigned int config; - uint32_t mpu_base; - int mpu_range; - uint32_t va_base; - unsigned int va_range; - struct kgsl_memdesc dummyspace; - /* current page table object being used by device mmu */ - struct kgsl_pagetable *defaultpagetable; - struct kgsl_pagetable *hwpagetable; - /* Maintain filter to manage tlb flushing */ - struct kgsl_tlbflushfilter tlbflushfilter; -}; - - -static inline int -kgsl_mmu_isenabled(struct kgsl_mmu *mmu) -{ - return ((mmu)->flags & KGSL_FLAGS_STARTED) ? 1 : 0; -} - - -int kgsl_mmu_init(struct kgsl_device *device); - -int kgsl_mmu_close(struct kgsl_device *device); - -struct kgsl_pagetable *kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu); - -int kgsl_mmu_destroypagetableobject(struct kgsl_pagetable *pagetable); - -int kgsl_mmu_setstate(struct kgsl_device *device, - struct kgsl_pagetable *pagetable); - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -int kgsl_mmu_map(struct kgsl_pagetable *pagetable, - unsigned int address, - int range, - unsigned int protflags, - unsigned int *gpuaddr, - unsigned int flags); - -int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, - unsigned int gpuaddr, int range); - -pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr); -#else -static inline int kgsl_mmu_map(struct kgsl_pagetable *pagetable, - unsigned int address, - int range, - unsigned int protflags, - unsigned int *gpuaddr, - unsigned int flags) -{ - *gpuaddr = address; - return 0; -} - -static inline int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, - unsigned int gpuaddr, int range) { return 0; } - -static inline pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr) {return NULL;} -#endif - -int kgsl_mmu_querystats(struct kgsl_pagetable *pagetable, - struct kgsl_ptstats *stats); - -void kgsl_mh_intrcallback(struct kgsl_device *device); - -#ifdef DEBUG -void kgsl_mmu_debug(struct kgsl_mmu *, struct kgsl_mmu_debug*); -#else -static inline void kgsl_mmu_debug(struct kgsl_mmu *mmu, - struct kgsl_mmu_debug *mmu_debug) { } -#endif /* DEBUG */ - -#endif /* __GSL_MMU_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_pm4types.h b/drivers/video/msm/gpu/kgsl/kgsl_pm4types.h deleted file mode 100644 index bc224b41..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_pm4types.h +++ /dev/null @@ -1,182 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef __GSL_PM4TYPES_H -#define __GSL_PM4TYPES_H - - -#define PM4_PKT_MASK 0xc0000000 - -#define PM4_TYPE0_PKT ((unsigned int)0 << 30) -#define PM4_TYPE1_PKT ((unsigned int)1 << 30) -#define PM4_TYPE2_PKT ((unsigned int)2 << 30) -#define PM4_TYPE3_PKT ((unsigned int)3 << 30) - - -/* type3 packets */ -/* initialize CP's micro-engine */ -#define PM4_ME_INIT 0x48 - -/* skip N 32-bit words to get to the next packet */ -#define PM4_NOP 0x10 - -/* indirect buffer dispatch. prefetch parser uses this packet type to determine -* whether to pre-fetch the IB -*/ -#define PM4_INDIRECT_BUFFER 0x3f - -/* indirect buffer dispatch. same as IB, but init is pipelined */ -#define PM4_INDIRECT_BUFFER_PFD 0x37 - -/* wait for the IDLE state of the engine */ -#define PM4_WAIT_FOR_IDLE 0x26 - -/* wait until a register or memory location is a specific value */ -#define PM4_WAIT_REG_MEM 0x3c - -/* wait until a register location is equal to a specific value */ -#define PM4_WAIT_REG_EQ 0x52 - -/* wait until a register location is >= a specific value */ -#define PM4_WAT_REG_GTE 0x53 - -/* wait until a read completes */ -#define PM4_WAIT_UNTIL_READ 0x5c - -/* wait until all base/size writes from an IB_PFD packet have completed */ -#define PM4_WAIT_IB_PFD_COMPLETE 0x5d - -/* register read/modify/write */ -#define PM4_REG_RMW 0x21 - -/* reads register in chip and writes to memory */ -#define PM4_REG_TO_MEM 0x3e - -/* write N 32-bit words to memory */ -#define PM4_MEM_WRITE 0x3d - -/* write CP_PROG_COUNTER value to memory */ -#define PM4_MEM_WRITE_CNTR 0x4f - -/* conditional execution of a sequence of packets */ -#define PM4_COND_EXEC 0x44 - -/* conditional write to memory or register */ -#define PM4_COND_WRITE 0x45 - -/* generate an event that creates a write to memory when completed */ -#define PM4_EVENT_WRITE 0x46 - -/* generate a VS|PS_done event */ -#define PM4_EVENT_WRITE_SHD 0x58 - -/* generate a cache flush done event */ -#define PM4_EVENT_WRITE_CFL 0x59 - -/* generate a z_pass done event */ -#define PM4_EVENT_WRITE_ZPD 0x5b - - -/* initiate fetch of index buffer and draw */ -#define PM4_DRAW_INDX 0x22 - -/* draw using supplied indices in packet */ -#define PM4_DRAW_INDX_2 0x36 - -/* initiate fetch of index buffer and binIDs and draw */ -#define PM4_DRAW_INDX_BIN 0x34 - -/* initiate fetch of bin IDs and draw using supplied indices */ -#define PM4_DRAW_INDX_2_BIN 0x35 - - -/* begin/end initiator for viz query extent processing */ -#define PM4_VIZ_QUERY 0x23 - -/* fetch state sub-blocks and initiate shader code DMAs */ -#define PM4_SET_STATE 0x25 - -/* load constant into chip and to memory */ -#define PM4_SET_CONSTANT 0x2d - -/* load sequencer instruction memory (pointer-based) */ -#define PM4_IM_LOAD 0x27 - -/* load sequencer instruction memory (code embedded in packet) */ -#define PM4_IM_LOAD_IMMEDIATE 0x2b - -/* load constants from a location in memory */ -#define PM4_LOAD_CONSTANT_CONTEXT 0x2e - -/* selective invalidation of state pointers */ -#define PM4_INVALIDATE_STATE 0x3b - - -/* dynamically changes shader instruction memory partition */ -#define PM4_SET_SHADER_BASES 0x4A - -/* sets the 64-bit BIN_MASK register in the PFP */ -#define PM4_SET_BIN_MASK 0x50 - -/* sets the 64-bit BIN_SELECT register in the PFP */ -#define PM4_SET_BIN_SELECT 0x51 - - -/* updates the current context, if needed */ -#define PM4_CONTEXT_UPDATE 0x5e - -/* generate interrupt from the command stream */ -#define PM4_INTERRUPT 0x40 - - -/* copy sequencer instruction memory to system memory */ -#define PM4_IM_STORE 0x2c - -/* program an offset that will added to the BIN_BASE value of - * the 3D_DRAW_INDX_BIN packet */ -#define PM4_SET_BIN_BASE_OFFSET 0x4B - -#define PM4_SET_PROTECTED_MODE 0x5f /* sets the register protection mode */ - -/* packet header building macros */ -#define pm4_type0_packet(regindx, cnt) \ - (PM4_TYPE0_PKT | (((cnt)-1) << 16) | ((regindx) & 0x7FFF)) - -#define pm4_type0_packet_for_sameregister(regindx, cnt) \ - ((PM4_TYPE0_PKT | (((cnt)-1) << 16) | ((1 << 15) | \ - ((regindx) & 0x7FFF))) - -#define pm4_type1_packet(reg0, reg1) \ - (PM4_TYPE1_PKT | ((reg1) << 12) | (reg0)) - -#define pm4_type3_packet(opcode, cnt) \ - (PM4_TYPE3_PKT | (((cnt)-1) << 16) | (((opcode) & 0xFF) << 8)) - -#define pm4_predicated_type3_packet(opcode, cnt) \ - (PM4_TYPE3_PKT | (((cnt)-1) << 16) | (((opcode) & 0xFF) << 8) | 0x1) - -#define pm4_nop_packet(cnt) \ - (PM4_TYPE3_PKT | (((cnt)-1) << 16) | (PM4_NOP << 8)) - - -/* packet headers */ -#define PM4_HDR_ME_INIT pm4_type3_packet(PM4_ME_INIT, 18) -#define PM4_HDR_INDIRECT_BUFFER_PFD pm4_type3_packet(PM4_INDIRECT_BUFFER_PFD, 2) -#define PM4_HDR_INDIRECT_BUFFER pm4_type3_packet(PM4_INDIRECT_BUFFER, 2) - -#endif /* __GSL_PM4TYPES_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c b/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c deleted file mode 100644 index 472d10c1..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include -#include -#include - -#include "kgsl.h" -#include "kgsl_device.h" -#include "kgsl_log.h" -#include "kgsl_pm4types.h" -#include "kgsl_ringbuffer.h" -#include "kgsl_cmdstream.h" - -#include "yamato_reg.h" - -#define GSL_RB_NOP_SIZEDWORDS 2 -/* protected mode error checking below register address 0x800 -* note: if CP_INTERRUPT packet is used then checking needs -* to change to below register address 0x7C8 -*/ -#define GSL_RB_PROTECTED_MODE_CONTROL 0x200001F2 - -#define GSL_CP_INT_MASK \ - (CP_INT_CNTL__SW_INT_MASK | \ - CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \ - CP_INT_CNTL__OPCODE_ERROR_MASK | \ - CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \ - CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \ - CP_INT_CNTL__IB_ERROR_MASK | \ - CP_INT_CNTL__IB2_INT_MASK | \ - CP_INT_CNTL__IB1_INT_MASK | \ - CP_INT_CNTL__RB_INT_MASK) - -#define YAMATO_PFP_FW "yamato_pfp.fw" -#define YAMATO_PM4_FW "yamato_pm4.fw" - -/* ringbuffer size log2 quadwords equivalent */ -inline unsigned int kgsl_ringbuffer_sizelog2quadwords(unsigned int sizedwords) -{ - unsigned int sizelog2quadwords = 0; - int i = sizedwords >> 1; - - while (i >>= 1) - sizelog2quadwords++; - - return sizelog2quadwords; -} - - -/* functions */ -void kgsl_cp_intrcallback(struct kgsl_device *device) -{ - unsigned int status = 0; - struct kgsl_ringbuffer *rb = &device->ringbuffer; - - KGSL_CMD_VDBG("enter (device=%p)\n", device); - - kgsl_yamato_regread(device, REG_CP_INT_STATUS, &status); - - if (status & CP_INT_CNTL__RB_INT_MASK) { - /* signal intr completion event */ - int init_reftimestamp = 0x7fffffff; - int enableflag = 0; - kgsl_sharedmem_write(&rb->device->memstore, - KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable), - &enableflag, 4); - kgsl_sharedmem_write(&rb->device->memstore, - KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts), - &init_reftimestamp, 4); - KGSL_CMD_WARN("ringbuffer rb interrupt\n"); - } - - if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) { - KGSL_CMD_WARN("ringbuffer ib1/rb interrupt\n"); - wake_up_interruptible_all(&device->ib1_wq); - } - if (status & CP_INT_CNTL__T0_PACKET_IN_IB_MASK) { - KGSL_CMD_FATAL("ringbuffer TO packet in IB interrupt\n"); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - kgsl_ringbuffer_dump(rb); - } - if (status & CP_INT_CNTL__OPCODE_ERROR_MASK) { - KGSL_CMD_FATAL("ringbuffer opcode error interrupt\n"); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - kgsl_ringbuffer_dump(rb); - } - if (status & CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK) { - KGSL_CMD_FATAL("ringbuffer protected mode error interrupt\n"); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - kgsl_ringbuffer_dump(rb); - } - if (status & CP_INT_CNTL__RESERVED_BIT_ERROR_MASK) { - KGSL_CMD_FATAL("ringbuffer reserved bit error interrupt\n"); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - kgsl_ringbuffer_dump(rb); - } - if (status & CP_INT_CNTL__IB_ERROR_MASK) { - KGSL_CMD_FATAL("ringbuffer IB error interrupt\n"); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - kgsl_ringbuffer_dump(rb); - } - if (status & CP_INT_CNTL__SW_INT_MASK) - KGSL_CMD_DBG("ringbuffer software interrupt\n"); - - if (status & CP_INT_CNTL__IB2_INT_MASK) - KGSL_CMD_DBG("ringbuffer ib2 interrupt\n"); - - if (status & (~GSL_CP_INT_MASK)) - KGSL_CMD_DBG("bad bits in REG_CP_INT_STATUS %08x\n", status); - - /* only ack bits we understand */ - status &= GSL_CP_INT_MASK; - kgsl_yamato_regwrite(device, REG_CP_INT_ACK, status); - - KGSL_CMD_VDBG("return\n"); -} - - -void kgsl_ringbuffer_watchdog() -{ - struct kgsl_device *device = NULL; - struct kgsl_ringbuffer *rb = NULL; - - device = &kgsl_driver.yamato_device; - - BUG_ON(device == NULL); - - rb = &device->ringbuffer; - - KGSL_CMD_VDBG("enter\n"); - - if ((rb->flags & KGSL_FLAGS_STARTED) == 0) { - KGSL_CMD_VDBG("not started\n"); - return; - } - - GSL_RB_GET_READPTR(rb, &rb->rptr); - - if (rb->rptr == rb->wptr) { - /* clear rptr sample for interval n */ - rb->watchdog.flags &= ~KGSL_FLAGS_ACTIVE; - goto done; - } - /* ringbuffer is currently not empty */ - /* and a rptr sample was taken during interval n-1 */ - if (rb->watchdog.flags & KGSL_FLAGS_ACTIVE) { - /* and the rptr did not advance between - * interval n-1 and n */ - if (rb->rptr == rb->watchdog.rptr_sample) { - /* then the core has hung */ - KGSL_CMD_FATAL("Watchdog detected core hung.\n"); - goto done; - } - /* save rptr sample for interval n */ - rb->watchdog.flags |= KGSL_FLAGS_ACTIVE; - rb->watchdog.rptr_sample = rb->rptr; - } -done: - KGSL_CMD_VDBG("return\n"); -} - -static void kgsl_ringbuffer_submit(struct kgsl_ringbuffer *rb) -{ - BUG_ON(rb->wptr == 0); - - GSL_RB_UPDATE_WPTR_POLLING(rb); - /* Drain write buffer and data memory barrier */ - dsb(); - dmb(); - - /* Memory fence to ensure all data has posted. On some systems, - * like 7x27, the register block is not allocated as strongly ordered - * memory. Adding a memory fence ensures ordering during ringbuffer - * submits.*/ - mb(); - - kgsl_yamato_regwrite(rb->device, REG_CP_RB_WPTR, rb->wptr); - - rb->flags |= KGSL_FLAGS_ACTIVE; -} - -static int -kgsl_ringbuffer_waitspace(struct kgsl_ringbuffer *rb, unsigned int numcmds, - int wptr_ahead) -{ - int nopcount; - unsigned int freecmds; - unsigned int *cmds; - - KGSL_CMD_VDBG("enter (rb=%p, numcmds=%d, wptr_ahead=%d)\n", - rb, numcmds, wptr_ahead); - - /* if wptr ahead, fill the remaining with NOPs */ - if (wptr_ahead) { - /* -1 for header */ - nopcount = rb->sizedwords - rb->wptr - 1; - - cmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr; - GSL_RB_WRITE(cmds, pm4_nop_packet(nopcount)); - rb->wptr++; - - kgsl_ringbuffer_submit(rb); - - rb->wptr = 0; - } - - /* wait for space in ringbuffer */ - do { - GSL_RB_GET_READPTR(rb, &rb->rptr); - - freecmds = rb->rptr - rb->wptr; - - } while ((freecmds != 0) && (freecmds < numcmds)); - - KGSL_CMD_VDBG("return %d\n", 0); - - return 0; -} - - -static unsigned int *kgsl_ringbuffer_allocspace(struct kgsl_ringbuffer *rb, - unsigned int numcmds) -{ - unsigned int *ptr = NULL; - int status = 0; - - BUG_ON(numcmds >= rb->sizedwords); - - /* check for available space */ - if (rb->wptr >= rb->rptr) { - /* wptr ahead or equal to rptr */ - /* reserve dwords for nop packet */ - if ((rb->wptr + numcmds) > (rb->sizedwords - - GSL_RB_NOP_SIZEDWORDS)) - status = kgsl_ringbuffer_waitspace(rb, numcmds, 1); - } else { - /* wptr behind rptr */ - if ((rb->wptr + numcmds) >= rb->rptr) - status = kgsl_ringbuffer_waitspace(rb, numcmds, 0); - /* check for remaining space */ - /* reserve dwords for nop packet */ - if ((rb->wptr + numcmds) > (rb->sizedwords - - GSL_RB_NOP_SIZEDWORDS)) - status = kgsl_ringbuffer_waitspace(rb, numcmds, 1); - } - - if (status == 0) { - ptr = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr; - rb->wptr += numcmds; - } - - return ptr; -} - -static int kgsl_ringbuffer_load_pm4_ucode(struct kgsl_device *device) -{ - int status = 0; - int i; - const struct firmware *fw = NULL; - unsigned int *fw_ptr = NULL; - size_t fw_word_size = 0; - - status = request_firmware(&fw, YAMATO_PM4_FW, - kgsl_driver.misc.this_device); - if (status != 0) { - KGSL_DRV_ERR("request_firmware failed for %s with error %d\n", - YAMATO_PM4_FW, status); - goto done; - } - /*this firmware must come in 3 word chunks. plus 1 word of version*/ - if ((fw->size % (sizeof(uint32_t)*3)) != 4) { - KGSL_DRV_ERR("bad firmware size %d.\n", fw->size); - status = -EINVAL; - goto done; - } - fw_ptr = (unsigned int *)fw->data; - fw_word_size = fw->size/sizeof(uint32_t); - KGSL_DRV_INFO("loading pm4 ucode version: %d\n", fw_ptr[0]); - - kgsl_yamato_regwrite(device, REG_CP_DEBUG, 0x02000000); - kgsl_yamato_regwrite(device, REG_CP_ME_RAM_WADDR, 0); - for (i = 1; i < fw_word_size; i++) - kgsl_yamato_regwrite(device, REG_CP_ME_RAM_DATA, fw_ptr[i]); - -done: - release_firmware(fw); - return status; -} - -static int kgsl_ringbuffer_load_pfp_ucode(struct kgsl_device *device) -{ - int status = 0; - int i; - const struct firmware *fw = NULL; - unsigned int *fw_ptr = NULL; - size_t fw_word_size = 0; - - status = request_firmware(&fw, YAMATO_PFP_FW, - kgsl_driver.misc.this_device); - if (status != 0) { - KGSL_DRV_ERR("request_firmware for %s failed with error %d\n", - YAMATO_PFP_FW, status); - return status; - } - /*this firmware must come in 1 word chunks. */ - if ((fw->size % sizeof(uint32_t)) != 0) { - KGSL_DRV_ERR("bad firmware size %d.\n", fw->size); - release_firmware(fw); - return -EINVAL; - } - fw_ptr = (unsigned int *)fw->data; - fw_word_size = fw->size/sizeof(uint32_t); - - KGSL_DRV_INFO("loading pfp ucode version: %d\n", fw_ptr[0]); - - kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_ADDR, 0); - for (i = 1; i < fw_word_size; i++) - kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_DATA, fw_ptr[i]); - - release_firmware(fw); - return status; -} - -static int kgsl_ringbuffer_start(struct kgsl_ringbuffer *rb) -{ - int status; - /*cp_rb_cntl_u cp_rb_cntl; */ - union reg_cp_rb_cntl cp_rb_cntl; - unsigned int *cmds, rb_cntl; - struct kgsl_device *device = rb->device; - - KGSL_CMD_VDBG("enter (rb=%p)\n", rb); - - if (rb->flags & KGSL_FLAGS_STARTED) { - KGSL_CMD_VDBG("return %d\n", 0); - return 0; - } - kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0, - sizeof(struct kgsl_rbmemptrs)); - - kgsl_sharedmem_set(&rb->buffer_desc, 0, 0xAA, - (rb->sizedwords << 2)); - - kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_BASE, - (rb->memptrs_desc.gpuaddr - + GSL_RB_MEMPTRS_WPTRPOLL_OFFSET)); - - /* setup WPTR delay */ - kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_DELAY, 0 /*0x70000010 */); - - /*setup REG_CP_RB_CNTL */ - kgsl_yamato_regread(device, REG_CP_RB_CNTL, &rb_cntl); - cp_rb_cntl.val = rb_cntl; - /* size of ringbuffer */ - cp_rb_cntl.f.rb_bufsz = - kgsl_ringbuffer_sizelog2quadwords(rb->sizedwords); - /* quadwords to read before updating mem RPTR */ - cp_rb_cntl.f.rb_blksz = rb->blksizequadwords; - cp_rb_cntl.f.rb_poll_en = GSL_RB_CNTL_POLL_EN; /* WPTR polling */ - /* mem RPTR writebacks */ - cp_rb_cntl.f.rb_no_update = GSL_RB_CNTL_NO_UPDATE; - - kgsl_yamato_regwrite(device, REG_CP_RB_CNTL, cp_rb_cntl.val); - - kgsl_yamato_regwrite(device, REG_CP_RB_BASE, rb->buffer_desc.gpuaddr); - - kgsl_yamato_regwrite(device, REG_CP_RB_RPTR_ADDR, - rb->memptrs_desc.gpuaddr + - GSL_RB_MEMPTRS_RPTR_OFFSET); - - /* explicitly clear all cp interrupts */ - kgsl_yamato_regwrite(device, REG_CP_INT_ACK, 0xFFFFFFFF); - - /* setup scratch/timestamp */ - kgsl_yamato_regwrite(device, REG_SCRATCH_ADDR, - device->memstore.gpuaddr + - KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp)); - - kgsl_yamato_regwrite(device, REG_SCRATCH_UMSK, - GSL_RB_MEMPTRS_SCRATCH_MASK); - - /* load the CP ucode */ - - status = kgsl_ringbuffer_load_pm4_ucode(device); - if (status != 0) { - KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n", - status); - return status; - } - - - /* load the prefetch parser ucode */ - status = kgsl_ringbuffer_load_pfp_ucode(device); - if (status != 0) { - KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n", - status); - return status; - } - - kgsl_yamato_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x000C0804); - - rb->rptr = 0; - rb->wptr = 0; - - rb->timestamp = 0; - GSL_RB_INIT_TIMESTAMP(rb); - - INIT_LIST_HEAD(&rb->memqueue); - - /* clear ME_HALT to start micro engine */ - kgsl_yamato_regwrite(device, REG_CP_ME_CNTL, 0); - - /* ME_INIT */ - cmds = kgsl_ringbuffer_allocspace(rb, 19); - - GSL_RB_WRITE(cmds, PM4_HDR_ME_INIT); - /* All fields present (bits 9:0) */ - GSL_RB_WRITE(cmds, 0x000003ff); - /* Disable/Enable Real-Time Stream processing (present but ignored) */ - GSL_RB_WRITE(cmds, 0x00000000); - /* Enable (2D <-> 3D) implicit synchronization (present but ignored) */ - GSL_RB_WRITE(cmds, 0x00000000); - - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE)); - GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL)); - GSL_RB_WRITE(cmds, - GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE)); - - /* Vertex and Pixel Shader Start Addresses in instructions - * (3 DWORDS per instruction) */ - GSL_RB_WRITE(cmds, 0x80000180); - /* Maximum Contexts */ - GSL_RB_WRITE(cmds, 0x00000001); - /* Write Confirm Interval and The CP will wait the - * wait_interval * 16 clocks between polling */ - GSL_RB_WRITE(cmds, 0x00000000); - - /* NQ and External Memory Swap */ - GSL_RB_WRITE(cmds, 0x00000000); - /* Protected mode error checking */ - GSL_RB_WRITE(cmds, GSL_RB_PROTECTED_MODE_CONTROL); - /* Disable header dumping and Header dump address */ - GSL_RB_WRITE(cmds, 0x00000000); - /* Header dump size */ - GSL_RB_WRITE(cmds, 0x00000000); - - kgsl_ringbuffer_submit(rb); - - /* idle device to validate ME INIT */ - status = kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - - KGSL_CMD_DBG("enabling CP interrupts: mask %08lx\n", GSL_CP_INT_MASK); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, GSL_CP_INT_MASK); - if (status == 0) - rb->flags |= KGSL_FLAGS_STARTED; - - KGSL_CMD_VDBG("return %d\n", status); - - return status; -} - -static int kgsl_ringbuffer_stop(struct kgsl_ringbuffer *rb) -{ - KGSL_CMD_VDBG("enter (rb=%p)\n", rb); - - if (rb->flags & KGSL_FLAGS_STARTED) { - KGSL_CMD_DBG("disabling CP interrupts: mask %08x\n", 0); - kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0); - - /* ME_HALT */ - kgsl_yamato_regwrite(rb->device, REG_CP_ME_CNTL, 0x10000000); - - rb->flags &= ~KGSL_FLAGS_STARTED; - kgsl_ringbuffer_dump(rb); - } - - KGSL_CMD_VDBG("return %d\n", 0); - - return 0; -} - -int kgsl_ringbuffer_init(struct kgsl_device *device) -{ - int status; - uint32_t flags; - struct kgsl_ringbuffer *rb = &device->ringbuffer; - - KGSL_CMD_VDBG("enter (device=%p)\n", device); - - rb->device = device; - rb->sizedwords = (2 << kgsl_cfg_rb_sizelog2quadwords); - rb->blksizequadwords = kgsl_cfg_rb_blksizequadwords; - - /* allocate memory for ringbuffer, needs to be double octword aligned - * align on page from contiguous physical memory - */ - flags = - (KGSL_MEMFLAGS_ALIGNPAGE | KGSL_MEMFLAGS_CONPHYS | - KGSL_MEMFLAGS_STRICTREQUEST); - - status = kgsl_sharedmem_alloc(flags, (rb->sizedwords << 2), - &rb->buffer_desc); - - if (status != 0) { - kgsl_ringbuffer_close(rb); - KGSL_CMD_VDBG("return %d\n", status); - return status; - } - - /* allocate memory for polling and timestamps */ - /* This really can be at 4 byte alignment boundry but for using MMU - * we need to make it at page boundary */ - flags = (KGSL_MEMFLAGS_ALIGNPAGE | KGSL_MEMFLAGS_CONPHYS); - - status = kgsl_sharedmem_alloc(flags, sizeof(struct kgsl_rbmemptrs), - &rb->memptrs_desc); - - if (status != 0) { - kgsl_ringbuffer_close(rb); - KGSL_CMD_VDBG("return %d\n", status); - return status; - } - - /* last allocation of init process is made here so map all - * allocations to MMU */ - status = kgsl_yamato_setup_pt(device, device->mmu.defaultpagetable); - if (status != 0) { - kgsl_ringbuffer_close(rb); - KGSL_CMD_VDBG("return %d\n", status); - return status; - } - - /* overlay structure on memptrs memory */ - rb->memptrs = (struct kgsl_rbmemptrs *) rb->memptrs_desc.hostptr; - - rb->flags |= KGSL_FLAGS_INITIALIZED; - - status = kgsl_ringbuffer_start(rb); - if (status != 0) { - kgsl_ringbuffer_close(rb); - KGSL_CMD_VDBG("return %d\n", status); - return status; - } - - KGSL_CMD_VDBG("return %d\n", 0); - return 0; -} - -int kgsl_ringbuffer_close(struct kgsl_ringbuffer *rb) -{ - KGSL_CMD_VDBG("enter (rb=%p)\n", rb); - - kgsl_cmdstream_memqueue_drain(rb->device); - - kgsl_ringbuffer_stop(rb); - - /* this must happen before first sharedmem_free */ - kgsl_yamato_cleanup_pt(rb->device, rb->device->mmu.defaultpagetable); - - if (rb->buffer_desc.hostptr) - kgsl_sharedmem_free(&rb->buffer_desc); - - if (rb->memptrs_desc.hostptr) - kgsl_sharedmem_free(&rb->memptrs_desc); - - rb->flags &= ~KGSL_FLAGS_INITIALIZED; - - memset(rb, 0, sizeof(struct kgsl_ringbuffer)); - - KGSL_CMD_VDBG("return %d\n", 0); - return 0; -} - -static uint32_t -kgsl_ringbuffer_addcmds(struct kgsl_ringbuffer *rb, - int flags, unsigned int *cmds, - int sizedwords) -{ - unsigned int *ringcmds; - unsigned int timestamp; - unsigned int total_sizedwords = sizedwords + 6; - - /* reserve space to temporarily turn off protected mode - * error checking if needed - */ - total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0; - total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 9 : 0; - - ringcmds = kgsl_ringbuffer_allocspace(rb, total_sizedwords); - - if (flags & KGSL_CMD_FLAGS_PMODE) { - /* disable protected mode error checking */ - *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); - *ringcmds++ = 0; - } - - memcpy(ringcmds, cmds, (sizedwords << 2)); - - ringcmds += sizedwords; - - if (flags & KGSL_CMD_FLAGS_PMODE) { - /* re-enable protected mode error checking */ - *ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1); - *ringcmds++ = 1; - } - - rb->timestamp++; - timestamp = rb->timestamp; - - /* start-of-pipeline and end-of-pipeline timestamps */ - *ringcmds++ = pm4_type0_packet(REG_CP_TIMESTAMP, 1); - *ringcmds++ = rb->timestamp; - *ringcmds++ = pm4_type3_packet(PM4_EVENT_WRITE, 3); - *ringcmds++ = CACHE_FLUSH_TS; - *ringcmds++ = - (rb->device->memstore.gpuaddr + - KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp)); - *ringcmds++ = rb->timestamp; - - if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) { - /* Add idle packet so avoid RBBM errors */ - *ringcmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *ringcmds++ = 0x00000000; - /* Conditional execution based on memory values */ - *ringcmds++ = pm4_type3_packet(PM4_COND_EXEC, 4); - *ringcmds++ = (rb->device->memstore.gpuaddr + - KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2; - *ringcmds++ = (rb->device->memstore.gpuaddr + - KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2; - *ringcmds++ = rb->timestamp; - /* # of conditional command DWORDs */ - *ringcmds++ = 2; - *ringcmds++ = pm4_type3_packet(PM4_INTERRUPT, 1); - *ringcmds++ = CP_INT_CNTL__RB_INT_MASK; - } - - kgsl_ringbuffer_submit(rb); - - GSL_RB_STATS(rb->stats.words_total += sizedwords); - GSL_RB_STATS(rb->stats.issues++); - - KGSL_CMD_VDBG("return %d\n", timestamp); - - /* return timestamp of issued coREG_ands */ - return timestamp; -} - -uint32_t -kgsl_ringbuffer_issuecmds(struct kgsl_device *device, - int flags, - unsigned int *cmds, - int sizedwords) -{ - unsigned int timestamp; - struct kgsl_ringbuffer *rb = &device->ringbuffer; - - KGSL_CMD_VDBG("enter (device->id=%d, flags=%d, cmds=%p, " - "sizedwords=%d)\n", device->id, flags, cmds, sizedwords); - - timestamp = kgsl_ringbuffer_addcmds(rb, flags, cmds, sizedwords); - - KGSL_CMD_VDBG("return %d\n)", timestamp); - return timestamp; -} - -int -kgsl_ringbuffer_issueibcmds(struct kgsl_device *device, - int drawctxt_index, - uint32_t ibaddr, - int sizedwords, - uint32_t *timestamp, - unsigned int flags) -{ - unsigned int link[3]; - - KGSL_CMD_VDBG("enter (device_id=%d, drawctxt_index=%d, ibaddr=0x%08x," - " sizedwords=%d, timestamp=%p)\n", - device->id, drawctxt_index, ibaddr, - sizedwords, timestamp); - - if (!(device->ringbuffer.flags & KGSL_FLAGS_STARTED)) { - KGSL_CMD_VDBG("return %d\n", -EINVAL); - return -EINVAL; - } - - BUG_ON(ibaddr == 0); - BUG_ON(sizedwords == 0); - - link[0] = PM4_HDR_INDIRECT_BUFFER_PFD; - link[1] = ibaddr; - link[2] = sizedwords; - - kgsl_drawctxt_switch(device, &device->drawctxt[drawctxt_index], flags); - - *timestamp = kgsl_ringbuffer_addcmds(&device->ringbuffer, - 0, &link[0], 3); - - - KGSL_CMD_INFO("ctxt %d g %08x sd %d ts %d\n", - drawctxt_index, ibaddr, sizedwords, *timestamp); - - KGSL_CMD_VDBG("return %d\n", 0); - - return 0; -} - - -#ifdef DEBUG -void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb, - struct kgsl_rb_debug *rb_debug) -{ - memset(rb_debug, 0, sizeof(struct kgsl_rb_debug)); - - rb_debug->mem_rptr = rb->memptrs->rptr; - rb_debug->mem_wptr_poll = rb->memptrs->wptr_poll; - kgsl_yamato_regread(rb->device, REG_CP_RB_BASE, - (unsigned int *)&rb_debug->cp_rb_base); - kgsl_yamato_regread(rb->device, REG_CP_RB_CNTL, - (unsigned int *)&rb_debug->cp_rb_cntl); - kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR_ADDR, - (unsigned int *)&rb_debug->cp_rb_rptr_addr); - kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR, - (unsigned int *)&rb_debug->cp_rb_rptr); - kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR_WR, - (unsigned int *)&rb_debug->cp_rb_rptr_wr); - kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR, - (unsigned int *)&rb_debug->cp_rb_wptr); - kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR_DELAY, - (unsigned int *)&rb_debug->cp_rb_wptr_delay); - kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR_BASE, - (unsigned int *)&rb_debug->cp_rb_wptr_base); - kgsl_yamato_regread(rb->device, REG_CP_IB1_BASE, - (unsigned int *)&rb_debug->cp_ib1_base); - kgsl_yamato_regread(rb->device, REG_CP_IB1_BUFSZ, - (unsigned int *)&rb_debug->cp_ib1_bufsz); - kgsl_yamato_regread(rb->device, REG_CP_IB2_BASE, - (unsigned int *)&rb_debug->cp_ib2_base); - kgsl_yamato_regread(rb->device, REG_CP_IB2_BUFSZ, - (unsigned int *)&rb_debug->cp_ib2_bufsz); - kgsl_yamato_regread(rb->device, REG_CP_ST_BASE, - (unsigned int *)&rb_debug->cp_st_base); - kgsl_yamato_regread(rb->device, REG_CP_ST_BUFSZ, - (unsigned int *)&rb_debug->cp_st_bufsz); - kgsl_yamato_regread(rb->device, REG_CP_CSQ_RB_STAT, - (unsigned int *)&rb_debug->cp_csq_rb_stat); - kgsl_yamato_regread(rb->device, REG_CP_CSQ_IB1_STAT, - (unsigned int *)&rb_debug->cp_csq_ib1_stat); - kgsl_yamato_regread(rb->device, REG_CP_CSQ_IB2_STAT, - (unsigned int *)&rb_debug->cp_csq_ib2_stat); - kgsl_yamato_regread(rb->device, REG_SCRATCH_UMSK, - (unsigned int *)&rb_debug->scratch_umsk); - kgsl_yamato_regread(rb->device, REG_SCRATCH_ADDR, - (unsigned int *)&rb_debug->scratch_addr); - kgsl_yamato_regread(rb->device, REG_CP_ME_CNTL, - (unsigned int *)&rb_debug->cp_me_cntl); - kgsl_yamato_regread(rb->device, REG_CP_ME_STATUS, - (unsigned int *)&rb_debug->cp_me_status); - kgsl_yamato_regread(rb->device, REG_CP_DEBUG, - (unsigned int *)&rb_debug->cp_debug); - kgsl_yamato_regread(rb->device, REG_CP_STAT, - (unsigned int *)&rb_debug->cp_stat); - kgsl_yamato_regread(rb->device, REG_CP_INT_STATUS, - (unsigned int *)&rb_debug->cp_int_status); - kgsl_yamato_regread(rb->device, REG_CP_INT_CNTL, - (unsigned int *)&rb_debug->cp_int_cntl); - kgsl_yamato_regread(rb->device, REG_RBBM_STATUS, - (unsigned int *)&rb_debug->rbbm_status); - kgsl_yamato_regread(rb->device, REG_RBBM_INT_STATUS, - (unsigned int *)&rb_debug->rbbm_int_status); - GSL_RB_GET_SOP_TIMESTAMP(rb, (unsigned int *)&rb_debug->sop_timestamp); - GSL_RB_GET_EOP_TIMESTAMP(rb, (unsigned int *)&rb_debug->eop_timestamp); - -} -#endif /*DEBUG*/ - -#ifdef DEBUG -void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb) -{ - struct kgsl_rb_debug rb_debug; - kgsl_ringbuffer_debug(rb, &rb_debug); - - KGSL_CMD_DBG("rbbm_status %08x rbbm_int_status %08x" - " mem_rptr %08x mem_wptr_poll %08x\n", - rb_debug.rbbm_status, - rb_debug.rbbm_int_status, - rb_debug.mem_rptr, rb_debug.mem_wptr_poll); - - KGSL_CMD_DBG("rb_base %08x rb_cntl %08x rb_rptr_addr %08x rb_rptr %08x" - " rb_rptr_wr %08x\n", - rb_debug.cp_rb_base, rb_debug.cp_rb_cntl, - rb_debug.cp_rb_rptr_addr, rb_debug.cp_rb_rptr, - rb_debug.cp_rb_rptr_wr); - - KGSL_CMD_DBG("rb_wptr %08x rb_wptr_delay %08x rb_wptr_base %08x" - " ib1_base %08x ib1_bufsz %08x\n", - rb_debug.cp_rb_wptr, rb_debug.cp_rb_wptr_delay, - rb_debug.cp_rb_wptr_base, rb_debug.cp_ib1_base, - rb_debug.cp_ib1_bufsz); - - KGSL_CMD_DBG("ib2_base %08x ib2_bufsz %08x st_base %08x st_bufsz %08x" - " cp_me_cntl %08x cp_me_status %08x\n", - rb_debug.cp_ib2_base, rb_debug.cp_ib2_bufsz, - rb_debug.cp_st_base, rb_debug.cp_st_bufsz, - rb_debug.cp_me_cntl, rb_debug.cp_me_status); - - KGSL_CMD_DBG("cp_debug %08x cp_stat %08x cp_int_status %08x" - " cp_int_cntl %08x\n", - rb_debug.cp_debug, rb_debug.cp_stat, - rb_debug.cp_int_status, rb_debug.cp_int_cntl); - - KGSL_CMD_DBG("sop_timestamp: %d eop_timestamp: %d\n", - rb_debug.sop_timestamp, rb_debug.eop_timestamp); - -} -#endif /* DEBUG */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.h b/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.h deleted file mode 100644 index 0d060209..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_ringbuffer.h +++ /dev/null @@ -1,254 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef __GSL_RINGBUFFER_H -#define __GSL_RINGBUFFER_H - -#include -#include -#include -#include "kgsl_log.h" -#include "kgsl_sharedmem.h" -#include "yamato_reg.h" - -#define GSL_STATS_RINGBUFFER - -#define GSL_RB_USE_MEM_RPTR -#define GSL_RB_USE_MEM_TIMESTAMP -#define GSL_DEVICE_SHADOW_MEMSTORE_TO_USER - -/* ringbuffer sizes log2quadword */ -#define GSL_RB_SIZE_8 0 -#define GSL_RB_SIZE_16 1 -#define GSL_RB_SIZE_32 2 -#define GSL_RB_SIZE_64 3 -#define GSL_RB_SIZE_128 4 -#define GSL_RB_SIZE_256 5 -#define GSL_RB_SIZE_512 6 -#define GSL_RB_SIZE_1K 7 -#define GSL_RB_SIZE_2K 8 -#define GSL_RB_SIZE_4K 9 -#define GSL_RB_SIZE_8K 10 -#define GSL_RB_SIZE_16K 11 -#define GSL_RB_SIZE_32K 12 -#define GSL_RB_SIZE_64K 13 -#define GSL_RB_SIZE_128K 14 -#define GSL_RB_SIZE_256K 15 -#define GSL_RB_SIZE_512K 16 -#define GSL_RB_SIZE_1M 17 -#define GSL_RB_SIZE_2M 18 -#define GSL_RB_SIZE_4M 19 - -/* Yamato ringbuffer config*/ -static const unsigned int kgsl_cfg_rb_sizelog2quadwords = GSL_RB_SIZE_32K; -static const unsigned int kgsl_cfg_rb_blksizequadwords = GSL_RB_SIZE_16; - -/* CP timestamp register */ -#define REG_CP_TIMESTAMP REG_SCRATCH_REG0 - - -struct kgsl_device; -struct kgsl_drawctxt; -struct kgsl_ringbuffer; - -struct kgsl_rb_debug { - unsigned int pm4_ucode_rel; - unsigned int pfp_ucode_rel; - unsigned int mem_wptr_poll; - unsigned int mem_rptr; - unsigned int cp_rb_base; - unsigned int cp_rb_cntl; - unsigned int cp_rb_rptr_addr; - unsigned int cp_rb_rptr; - unsigned int cp_rb_rptr_wr; - unsigned int cp_rb_wptr; - unsigned int cp_rb_wptr_delay; - unsigned int cp_rb_wptr_base; - unsigned int cp_ib1_base; - unsigned int cp_ib1_bufsz; - unsigned int cp_ib2_base; - unsigned int cp_ib2_bufsz; - unsigned int cp_st_base; - unsigned int cp_st_bufsz; - unsigned int cp_csq_rb_stat; - unsigned int cp_csq_ib1_stat; - unsigned int cp_csq_ib2_stat; - unsigned int scratch_umsk; - unsigned int scratch_addr; - unsigned int cp_me_cntl; - unsigned int cp_me_status; - unsigned int cp_debug; - unsigned int cp_stat; - unsigned int cp_int_status; - unsigned int cp_int_cntl; - unsigned int rbbm_status; - unsigned int rbbm_int_status; - unsigned int sop_timestamp; - unsigned int eop_timestamp; -}; -#ifdef DEBUG -void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb, - struct kgsl_rb_debug *rb_debug); - -void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb); -#else -static inline void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb, - struct kgsl_rb_debug *rb_debug) -{ -} - -static inline void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb) -{ -} -#endif - -struct kgsl_rbwatchdog { - uint32_t flags; - unsigned int rptr_sample; -}; - -#define GSL_RB_MEMPTRS_SCRATCH_COUNT 8 -struct kgsl_rbmemptrs { - volatile int rptr; - volatile int wptr_poll; -} __attribute__ ((packed)); - -#define GSL_RB_MEMPTRS_RPTR_OFFSET \ - (offsetof(struct kgsl_rbmemptrs, rptr)) - -#define GSL_RB_MEMPTRS_WPTRPOLL_OFFSET \ - (offsetof(struct kgsl_rbmemptrs, wptr_poll)) - -struct kgsl_rbstats { - int64_t issues; - int64_t words_total; -}; - - -struct kgsl_ringbuffer { - struct kgsl_device *device; - uint32_t flags; - - struct kgsl_memdesc buffer_desc; - - struct kgsl_memdesc memptrs_desc; - struct kgsl_rbmemptrs *memptrs; - - /*ringbuffer size */ - unsigned int sizedwords; - unsigned int blksizequadwords; - - unsigned int wptr; /* write pointer offset in dwords from baseaddr */ - unsigned int rptr; /* read pointer offset in dwords from baseaddr */ - uint32_t timestamp; - - /* queue of memfrees pending timestamp elapse */ - struct list_head memqueue; - - struct kgsl_rbwatchdog watchdog; - -#ifdef GSL_STATS_RINGBUFFER - struct kgsl_rbstats stats; -#endif /* GSL_STATS_RINGBUFFER */ - -}; - -/* dword base address of the GFX decode space */ -#define GSL_HAL_SUBBLOCK_OFFSET(reg) ((unsigned int)((reg) - (0x2000))) - -#define GSL_RB_WRITE(ring, data) \ - do { \ - mb(); \ - writel(data, ring); \ - ring++; \ - } while (0) - -/* timestamp */ -#ifdef GSL_DEVICE_SHADOW_MEMSTORE_TO_USER -#define GSL_RB_USE_MEM_TIMESTAMP -#endif /* GSL_DEVICE_SHADOW_MEMSTORE_TO_USER */ - -#ifdef GSL_RB_USE_MEM_TIMESTAMP -/* enable timestamp (...scratch0) memory shadowing */ -#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x1 -#define GSL_RB_INIT_TIMESTAMP(rb) - -#else -#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x0 -#define GSL_RB_INIT_TIMESTAMP(rb) \ - kgsl_yamato_regwrite((rb)->device->id, REG_CP_TIMESTAMP, 0) - -#endif /* GSL_RB_USE_MEMTIMESTAMP */ - -/* mem rptr */ -#ifdef GSL_RB_USE_MEM_RPTR -#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */ -#define GSL_RB_GET_READPTR(rb, data) \ - do { \ - *(data) = (rb)->memptrs->rptr; \ - } while (0) -#else -#define GSL_RB_CNTL_NO_UPDATE 0x1 /* disable */ -#define GSL_RB_GET_READPTR(rb, data) \ - do { \ - kgsl_yamato_regread((rb)->device->id, REG_CP_RB_RPTR, (data)); \ - } while (0) -#endif /* GSL_RB_USE_MEMRPTR */ - -/* wptr polling */ -#ifdef GSL_RB_USE_WPTR_POLLING -#define GSL_RB_CNTL_POLL_EN 0x1 /* enable */ -#define GSL_RB_UPDATE_WPTR_POLLING(rb) \ - do { (rb)->memptrs->wptr_poll = (rb)->wptr; } while (0) -#else -#define GSL_RB_CNTL_POLL_EN 0x0 /* disable */ -#define GSL_RB_UPDATE_WPTR_POLLING(rb) -#endif /* GSL_RB_USE_WPTR_POLLING */ - -/* stats */ -#ifdef GSL_STATS_RINGBUFFER -#define GSL_RB_STATS(x) x -#else -#define GSL_RB_STATS(x) -#endif /* GSL_STATS_RINGBUFFER */ - -struct kgsl_pmem_entry; - -int kgsl_ringbuffer_issueibcmds(struct kgsl_device *, int drawctxt_index, - uint32_t ibaddr, int sizedwords, - uint32_t *timestamp, - unsigned int flags); - -int kgsl_ringbuffer_init(struct kgsl_device *device); - -int kgsl_ringbuffer_close(struct kgsl_ringbuffer *rb); - -uint32_t kgsl_ringbuffer_issuecmds(struct kgsl_device *device, - int pmodeoff, - unsigned int *cmdaddr, - int sizedwords); - -int kgsl_ringbuffer_gettimestampshadow(struct kgsl_device *device, - unsigned int *sopaddr, - unsigned int *eopaddr); - -void kgsl_ringbuffer_watchdog(void); - -void kgsl_cp_intrcallback(struct kgsl_device *device); - -#endif /* __GSL_RINGBUFFER_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.c b/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.c deleted file mode 100644 index 4a1b4212..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include -#include - -#include "kgsl_sharedmem.h" -#include "kgsl_device.h" -#include "kgsl.h" -#include "kgsl_log.h" - -/* block alignment shift count */ -static inline unsigned int -kgsl_memarena_get_order(uint32_t flags) -{ - unsigned int alignshift; - alignshift = ((flags & KGSL_MEMFLAGS_ALIGN_MASK) - >> KGSL_MEMFLAGS_ALIGN_SHIFT); - return alignshift; -} - -/* block alignment shift count */ -static inline unsigned int -kgsl_memarena_align(unsigned int address, unsigned int shift) -{ - unsigned int alignedbaseaddr = ((address) >> shift) << shift; - if (alignedbaseaddr < address) - alignedbaseaddr += (1 << shift); - - return alignedbaseaddr; -} - -int -kgsl_sharedmem_init(struct kgsl_sharedmem *shmem) -{ - int result = -EINVAL; - - if (!request_mem_region(shmem->physbase, shmem->size, DRIVER_NAME)) { - KGSL_MEM_ERR("request_mem_region failed\n"); - goto error; - } - - shmem->baseptr = ioremap(shmem->physbase, shmem->size); - KGSL_MEM_INFO("ioremap(shm) = %p\n", shmem->baseptr); - - if (shmem->baseptr == NULL) { - KGSL_MEM_ERR("ioremap failed for address %08x size %d\n", - shmem->physbase, shmem->size); - result = -ENODEV; - goto error_release_mem; - } - - shmem->pool = gen_pool_create(KGSL_PAGESIZE_SHIFT, -1); - if (shmem->pool == NULL) { - KGSL_MEM_ERR("gen_pool_create failed\n"); - result = -ENOMEM; - goto error_iounmap; - } - - if (gen_pool_add(shmem->pool, shmem->physbase, shmem->size, -1)) { - KGSL_MEM_ERR("gen_pool_create failed\n"); - result = -ENOMEM; - goto error_pool_destroy; - } - result = 0; - KGSL_MEM_INFO("physbase 0x%08x size 0x%08x baseptr 0x%p\n", - shmem->physbase, shmem->size, shmem->baseptr); - return 0; - -error_pool_destroy: - gen_pool_destroy(shmem->pool); -error_iounmap: - iounmap(shmem->baseptr); - shmem->baseptr = NULL; -error_release_mem: - release_mem_region(shmem->physbase, shmem->size); -error: - return result; -} - -int -kgsl_sharedmem_close(struct kgsl_sharedmem *shmem) -{ - if (shmem->pool) { - gen_pool_destroy(shmem->pool); - shmem->pool = NULL; - } - - if (shmem->baseptr != NULL) { - KGSL_MEM_INFO("iounmap(shm) = %p\n", shmem->baseptr); - iounmap(shmem->baseptr); - shmem->baseptr = NULL; - release_mem_region(shmem->physbase, shmem->size); - } - - return 0; -} -/* -* get the host mapped address for a hardware device address -*/ -static void *kgsl_memarena_gethostptr(struct kgsl_sharedmem *shmem, - uint32_t physaddr) -{ - void *result; - - KGSL_MEM_VDBG("enter (memarena=%p, physaddr=0x%08x)\n", - shmem, physaddr); - - BUG_ON(shmem == NULL); - - /* check address range */ - if (physaddr < shmem->physbase) - return NULL; - - if (physaddr >= shmem->physbase + shmem->size) - return NULL; - - if (shmem->baseptr == NULL) { - KGSL_MEM_VDBG("return: %p\n", NULL); - return NULL; - } - - result = ((physaddr - shmem->physbase) + shmem->baseptr); - - KGSL_MEM_VDBG("return: %p\n", result); - - return result; -} - - -int -kgsl_sharedmem_alloc(uint32_t flags, int size, - struct kgsl_memdesc *memdesc) -{ - struct kgsl_sharedmem *shmem; - int result = -ENOMEM; - unsigned int blksize; - unsigned int baseaddr; - unsigned int alignshift; - unsigned int alignedbaseaddr; - - KGSL_MEM_VDBG("enter (flags=0x%08x, size=%d, memdesc=%p)\n", - flags, size, memdesc); - - shmem = &kgsl_driver.shmem; - BUG_ON(memdesc == NULL); - BUG_ON(size <= 0); - - alignshift = kgsl_memarena_get_order(flags); - - size = ALIGN(size, KGSL_PAGESIZE); - blksize = size; - if (alignshift > KGSL_PAGESIZE_SHIFT) - blksize += (1 << alignshift) - KGSL_PAGESIZE; - - baseaddr = gen_pool_alloc(shmem->pool, blksize); - if (baseaddr == 0) { - KGSL_MEM_ERR("gen_pool_alloc failed\n"); - result = -ENOMEM; - goto done; - } - result = 0; - - if (alignshift > KGSL_PAGESIZE_SHIFT) { - alignedbaseaddr = ALIGN(baseaddr, (1 << alignshift)); - - KGSL_MEM_VDBG("ba %x al %x as %d m->as %d bs %x s %x\n", - baseaddr, alignedbaseaddr, alignshift, - KGSL_PAGESIZE_SHIFT, blksize, size); - if (alignedbaseaddr > baseaddr) { - KGSL_MEM_VDBG("physaddr %x free before %x size %x\n", - alignedbaseaddr, - baseaddr, alignedbaseaddr - baseaddr); - gen_pool_free(shmem->pool, baseaddr, - alignedbaseaddr - baseaddr); - blksize -= alignedbaseaddr - baseaddr; - } - if (blksize > size) { - KGSL_MEM_VDBG("physaddr %x free after %x size %x\n", - alignedbaseaddr, - alignedbaseaddr + size, - blksize - size); - gen_pool_free(shmem->pool, - alignedbaseaddr + size, - blksize - size); - } - } else { - alignedbaseaddr = baseaddr; - } - - memdesc->physaddr = alignedbaseaddr; - memdesc->hostptr = kgsl_memarena_gethostptr(shmem, memdesc->physaddr); - memdesc->size = size; - - KGSL_MEM_VDBG("ashift %d m->ashift %d blksize %d base %x abase %x\n", - alignshift, KGSL_PAGESIZE_SHIFT, blksize, baseaddr, - alignedbaseaddr); - -done: - if (result) - memset(memdesc, 0, sizeof(*memdesc)); - - - KGSL_MEM_VDBG("return: %d\n", result); - return result; -} - -void -kgsl_sharedmem_free(struct kgsl_memdesc *memdesc) -{ - struct kgsl_sharedmem *shmem = &kgsl_driver.shmem; - - KGSL_MEM_VDBG("enter (shmem=%p, memdesc=%p, physaddr=%08x, size=%d)\n", - shmem, memdesc, memdesc->physaddr, memdesc->size); - - BUG_ON(memdesc == NULL); - BUG_ON(memdesc->size <= 0); - BUG_ON(shmem->physbase > memdesc->physaddr); - BUG_ON((shmem->physbase + shmem->size) - < (memdesc->physaddr + memdesc->size)); - - gen_pool_free(shmem->pool, memdesc->physaddr, memdesc->size); - - memset(memdesc, 0, sizeof(struct kgsl_memdesc)); - KGSL_MEM_VDBG("return\n"); -} - -int -kgsl_sharedmem_read(const struct kgsl_memdesc *memdesc, void *dst, - unsigned int offsetbytes, unsigned int sizebytes) -{ - if (memdesc == NULL || memdesc->hostptr == NULL || dst == NULL) { - KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p dst %p\n", - memdesc, - (memdesc ? memdesc->hostptr : NULL), - dst); - return -EINVAL; - } - if (offsetbytes + sizebytes > memdesc->size) { - KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n", - offsetbytes, sizebytes, memdesc->size); - return -ERANGE; - } - memcpy(dst, memdesc->hostptr + offsetbytes, sizebytes); - return 0; -} - -int -kgsl_sharedmem_write(const struct kgsl_memdesc *memdesc, - unsigned int offsetbytes, - void *value, unsigned int sizebytes) -{ - if (memdesc == NULL || memdesc->hostptr == NULL) { - KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p\n", memdesc, - (memdesc ? memdesc->hostptr : NULL)); - return -EINVAL; - } - if (offsetbytes + sizebytes > memdesc->size) { - KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n", - offsetbytes, sizebytes, memdesc->size); - return -ERANGE; - } - memcpy(memdesc->hostptr + offsetbytes, value, sizebytes); - return 0; -} - -int -kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc, unsigned int offsetbytes, - unsigned int value, unsigned int sizebytes) -{ - if (memdesc == NULL || memdesc->hostptr == NULL) { - KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p\n", memdesc, - (memdesc ? memdesc->hostptr : NULL)); - return -EINVAL; - } - if (offsetbytes + sizebytes > memdesc->size) { - KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n", - offsetbytes, sizebytes, memdesc->size); - return -ERANGE; - } - memset(memdesc->hostptr + offsetbytes, value, sizebytes); - return 0; -} - diff --git a/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.h b/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.h deleted file mode 100644 index eaf84063..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_sharedmem.h +++ /dev/null @@ -1,111 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef __GSL_SHAREDMEM_H -#define __GSL_SHAREDMEM_H - -#include -#include - -#define KGSL_PAGESIZE 0x1000 -#define KGSL_PAGESIZE_SHIFT 12 -#define KGSL_PAGEMASK (~(KGSL_PAGESIZE - 1)) - -struct kgsl_pagetable; - -struct platform_device; -struct gen_pool; - -/* memory allocation flags */ -#define KGSL_MEMFLAGS_ANY 0x00000000 /*dont care*/ - -#define KGSL_MEMFLAGS_APERTUREANY 0x00000000 -#define KGSL_MEMFLAGS_EMEM 0x00000000 -#define KGSL_MEMFLAGS_CONPHYS 0x00001000 - -#define KGSL_MEMFLAGS_ALIGNANY 0x00000000 -#define KGSL_MEMFLAGS_ALIGN32 0x00000000 -#define KGSL_MEMFLAGS_ALIGN64 0x00060000 -#define KGSL_MEMFLAGS_ALIGN128 0x00070000 -#define KGSL_MEMFLAGS_ALIGN256 0x00080000 -#define KGSL_MEMFLAGS_ALIGN512 0x00090000 -#define KGSL_MEMFLAGS_ALIGN1K 0x000A0000 -#define KGSL_MEMFLAGS_ALIGN2K 0x000B0000 -#define KGSL_MEMFLAGS_ALIGN4K 0x000C0000 -#define KGSL_MEMFLAGS_ALIGN8K 0x000D0000 -#define KGSL_MEMFLAGS_ALIGN16K 0x000E0000 -#define KGSL_MEMFLAGS_ALIGN32K 0x000F0000 -#define KGSL_MEMFLAGS_ALIGN64K 0x00100000 -#define KGSL_MEMFLAGS_ALIGNPAGE KGSL_MEMFLAGS_ALIGN4K - -/* fail the alloc if the flags cannot be honored */ -#define KGSL_MEMFLAGS_STRICTREQUEST 0x80000000 - -#define KGSL_MEMFLAGS_APERTURE_MASK 0x0000F000 -#define KGSL_MEMFLAGS_ALIGN_MASK 0x00FF0000 - -#define KGSL_MEMFLAGS_APERTURE_SHIFT 12 -#define KGSL_MEMFLAGS_ALIGN_SHIFT 16 - - -/* shared memory allocation */ -struct kgsl_memdesc { - struct kgsl_pagetable *pagetable; - void *hostptr; - unsigned int gpuaddr; - unsigned int physaddr; - unsigned int size; - unsigned int priv; -}; - -struct kgsl_sharedmem { - void *baseptr; - unsigned int physbase; - unsigned int size; - struct gen_pool *pool; -}; - -int kgsl_sharedmem_alloc(uint32_t flags, int size, - struct kgsl_memdesc *memdesc); - -/*TODO: add protection flags */ -int kgsl_sharedmem_import(struct kgsl_pagetable *, - uint32_t phys_addr, - uint32_t size, - struct kgsl_memdesc *memdesc); - - -void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc); - - -int kgsl_sharedmem_read(const struct kgsl_memdesc *memdesc, void *dst, - unsigned int offsetbytes, unsigned int sizebytes); - -int kgsl_sharedmem_write(const struct kgsl_memdesc *memdesc, - unsigned int offsetbytes, void *value, - unsigned int sizebytes); - -int kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc, - unsigned int offsetbytes, unsigned int value, - unsigned int sizebytes); - -int kgsl_sharedmem_init(struct kgsl_sharedmem *shmem); - -int kgsl_sharedmem_close(struct kgsl_sharedmem *shmem); - -#endif /* __GSL_SHAREDMEM_H */ diff --git a/drivers/video/msm/gpu/kgsl/kgsl_yamato.c b/drivers/video/msm/gpu/kgsl/kgsl_yamato.c deleted file mode 100644 index b0d6eeec..00000000 --- a/drivers/video/msm/gpu/kgsl/kgsl_yamato.c +++ /dev/null @@ -1,1004 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#include -#include -#include -#include -#include -#include - -#include "kgsl.h" -#include "kgsl_log.h" -#include "kgsl_pm4types.h" -#include "kgsl_cmdstream.h" - -#include "yamato_reg.h" - -#define GSL_RBBM_INT_MASK \ - (RBBM_INT_CNTL__RDERR_INT_MASK | \ - RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK) - -#define GSL_SQ_INT_MASK \ - (SQ_INT_CNTL__PS_WATCHDOG_MASK | \ - SQ_INT_CNTL__VS_WATCHDOG_MASK) - -/* Yamato MH arbiter config*/ -#define KGSL_CFG_YAMATO_MHARB \ - (0x10 \ - | (0 << MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT) \ - | (0 << MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT) \ - | (0 << MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT) \ - | (0x8 << MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT) \ - | (1 << MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT)) - -void kgsl_register_dump(struct kgsl_device *device) -{ - unsigned int regValue; - - kgsl_yamato_regread(device, REG_RBBM_STATUS, ®Value); - KGSL_CMD_ERR("RBBM_STATUS = %8.8X\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_BASE, ®Value); - KGSL_CMD_ERR("CP_RB_BASE = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_CNTL, ®Value); - KGSL_CMD_ERR("CP_RB_CNTL = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_RPTR_ADDR, ®Value); - KGSL_CMD_ERR("CP_RB_RPTR_ADDR = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_RPTR, ®Value); - KGSL_CMD_ERR("CP_RB_RPTR = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_WPTR, ®Value); - KGSL_CMD_ERR("CP_RB_WPTR = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_RB_RPTR_WR, ®Value); - KGSL_CMD_ERR("CP_RB_RPTR_WR = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_INT_CNTL, ®Value); - KGSL_CMD_ERR("CP_INT_CNTL = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_INT_STATUS, ®Value); - KGSL_CMD_ERR("CP_INT_STATUS = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_ME_CNTL, ®Value); - KGSL_CMD_ERR("CP_ME_CNTL = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_ME_STATUS, ®Value); - KGSL_CMD_ERR("CP_ME_STATUS = %08x\n", regValue); - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE1, ®Value); - KGSL_CMD_ERR("RBBM_PM_OVERRIDE1 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_RBBM_PM_OVERRIDE2, ®Value); - KGSL_CMD_ERR("RBBM_PM_OVERRIDE2 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_RBBM_INT_CNTL, ®Value); - KGSL_CMD_ERR("RBBM_INT_CNTL = %08x\n", regValue); - kgsl_yamato_regread(device, REG_RBBM_INT_STATUS, ®Value); - KGSL_CMD_ERR("RBBM_INT_STATUS = %08x\n", regValue); - kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, ®Value); - KGSL_CMD_ERR("MASTER_INT_SIGNAL = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_IB1_BASE, ®Value); - KGSL_CMD_ERR("CP_IB1_BASE = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_IB1_BUFSZ, ®Value); - KGSL_CMD_ERR("CP_IB1_BUFSZ = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_IB2_BASE, ®Value); - KGSL_CMD_ERR("CP_IB2_BASE = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_IB2_BUFSZ, ®Value); - KGSL_CMD_ERR("CP_IB2_BUFSZ = %08x\n", regValue); - kgsl_yamato_regread(device, REG_CP_STAT, ®Value); - KGSL_CMD_ERR("CP_STAT = %08x\n", regValue); - kgsl_yamato_regread(device, REG_SCRATCH_REG0, ®Value); - KGSL_CMD_ERR("SCRATCH_REG0 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_COHER_SIZE_PM4, ®Value); - KGSL_CMD_ERR("COHER_SIZE_PM4 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_COHER_BASE_PM4, ®Value); - KGSL_CMD_ERR("COHER_BASE_PM4 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_COHER_STATUS_PM4, ®Value); - KGSL_CMD_ERR("COHER_STATUS_PM4 = %08x\n", regValue); - kgsl_yamato_regread(device, REG_RBBM_READ_ERROR, ®Value); - KGSL_CMD_ERR("RBBM_READ_ERROR = %08x\n", regValue); - kgsl_yamato_regread(device, REG_MH_AXI_ERROR, ®Value); - KGSL_CMD_ERR("MH_AXI_ERROR = %08x\n", regValue); -} - -static int kgsl_yamato_gmeminit(struct kgsl_device *device) -{ - union reg_rb_edram_info rb_edram_info; - unsigned int gmem_size; - unsigned int edram_value = 0; - - /* make sure edram range is aligned to size */ - BUG_ON(device->gmemspace.gpu_base & (device->gmemspace.sizebytes - 1)); - - /* get edram_size value equivalent */ - gmem_size = (device->gmemspace.sizebytes >> 14); - while (gmem_size >>= 1) - edram_value++; - - rb_edram_info.val = 0; - - rb_edram_info.f.edram_size = edram_value; - rb_edram_info.f.edram_mapping_mode = 0; /* EDRAM_MAP_UPPER */ - /* must be aligned to size */ - rb_edram_info.f.edram_range = (device->gmemspace.gpu_base >> 14); - - kgsl_yamato_regwrite(device, REG_RB_EDRAM_INFO, rb_edram_info.val); - - return 0; -} - -static int kgsl_yamato_gmemclose(struct kgsl_device *device) -{ - kgsl_yamato_regwrite(device, REG_RB_EDRAM_INFO, 0x00000000); - - return 0; -} - -void kgsl_yamato_rbbm_intrcallback(struct kgsl_device *device) -{ - unsigned int status = 0; - unsigned int rderr = 0; - - KGSL_DRV_VDBG("enter (device=%p)\n", device); - - kgsl_yamato_regread(device, REG_RBBM_INT_STATUS, &status); - - if (status & RBBM_INT_CNTL__RDERR_INT_MASK) { - kgsl_yamato_regread(device, REG_RBBM_READ_ERROR, &rderr); - KGSL_DRV_FATAL("rbbm read error interrupt: %08x\n", rderr); - } else if (status & RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK) { - KGSL_DRV_DBG("rbbm display update interrupt\n"); - } else if (status & RBBM_INT_CNTL__GUI_IDLE_INT_MASK) { - KGSL_DRV_DBG("rbbm gui idle interrupt\n"); - } else { - KGSL_CMD_DBG("bad bits in REG_CP_INT_STATUS %08x\n", status); - } - - status &= GSL_RBBM_INT_MASK; - kgsl_yamato_regwrite(device, REG_RBBM_INT_ACK, status); - - KGSL_DRV_VDBG("return\n"); -} - -void kgsl_yamato_sq_intrcallback(struct kgsl_device *device) -{ - unsigned int status = 0; - - KGSL_DRV_VDBG("enter (device=%p)\n", device); - - kgsl_yamato_regread(device, REG_SQ_INT_STATUS, &status); - - if (status & SQ_INT_CNTL__PS_WATCHDOG_MASK) - KGSL_DRV_DBG("sq ps watchdog interrupt\n"); - else if (status & SQ_INT_CNTL__VS_WATCHDOG_MASK) - KGSL_DRV_DBG("sq vs watchdog interrupt\n"); - else - KGSL_DRV_DBG("bad bits in REG_SQ_INT_STATUS %08x\n", status); - - - status &= GSL_SQ_INT_MASK; - kgsl_yamato_regwrite(device, REG_SQ_INT_ACK, status); - - KGSL_DRV_VDBG("return\n"); -} - -irqreturn_t kgsl_yamato_isr(int irq, void *data) -{ - irqreturn_t result = IRQ_NONE; - - struct kgsl_device *device = &kgsl_driver.yamato_device; - unsigned int status; - - kgsl_yamato_regread(device, REG_MASTER_INT_SIGNAL, &status); - - if (status & MASTER_INT_SIGNAL__MH_INT_STAT) { - kgsl_mh_intrcallback(device); - result = IRQ_HANDLED; - } - - if (status & MASTER_INT_SIGNAL__CP_INT_STAT) { - kgsl_cp_intrcallback(device); - result = IRQ_HANDLED; - } - - if (status & MASTER_INT_SIGNAL__RBBM_INT_STAT) { - kgsl_yamato_rbbm_intrcallback(device); - result = IRQ_HANDLED; - } - - if (status & MASTER_INT_SIGNAL__SQ_INT_STAT) { - kgsl_yamato_sq_intrcallback(device); - result = IRQ_HANDLED; - } - - - return result; -} - -int kgsl_yamato_cleanup_pt(struct kgsl_device *device, - struct kgsl_pagetable *pagetable) -{ - kgsl_mmu_unmap(pagetable, device->ringbuffer.buffer_desc.gpuaddr, - device->ringbuffer.buffer_desc.size); - - kgsl_mmu_unmap(pagetable, device->ringbuffer.memptrs_desc.gpuaddr, - device->ringbuffer.memptrs_desc.size); - - kgsl_mmu_unmap(pagetable, device->memstore.gpuaddr, - device->memstore.size); - - kgsl_mmu_unmap(pagetable, device->mmu.dummyspace.gpuaddr, - device->mmu.dummyspace.size); - - return 0; -} - -int kgsl_yamato_setup_pt(struct kgsl_device *device, - struct kgsl_pagetable *pagetable) -{ - int result = 0; - unsigned int gpuaddr; - - BUG_ON(device->ringbuffer.buffer_desc.physaddr == 0); - BUG_ON(device->ringbuffer.memptrs_desc.physaddr == 0); - BUG_ON(device->memstore.physaddr == 0); - BUG_ON(device->mmu.dummyspace.physaddr == 0); - - result = kgsl_mmu_map(pagetable, - device->ringbuffer.buffer_desc.physaddr, - device->ringbuffer.buffer_desc.size, - GSL_PT_PAGE_RV, &gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN4K); - - if (result) - goto error; - - if (device->ringbuffer.buffer_desc.gpuaddr == 0) - device->ringbuffer.buffer_desc.gpuaddr = gpuaddr; - BUG_ON(device->ringbuffer.buffer_desc.gpuaddr != gpuaddr); - - result = kgsl_mmu_map(pagetable, - device->ringbuffer.memptrs_desc.physaddr, - device->ringbuffer.memptrs_desc.size, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, &gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN4K); - if (result) - goto unmap_buffer_desc; - - if (device->ringbuffer.memptrs_desc.gpuaddr == 0) - device->ringbuffer.memptrs_desc.gpuaddr = gpuaddr; - BUG_ON(device->ringbuffer.memptrs_desc.gpuaddr != gpuaddr); - - result = kgsl_mmu_map(pagetable, device->memstore.physaddr, - device->memstore.size, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, &gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN4K); - if (result) - goto unmap_memptrs_desc; - - if (device->memstore.gpuaddr == 0) - device->memstore.gpuaddr = gpuaddr; - BUG_ON(device->memstore.gpuaddr != gpuaddr); - - result = kgsl_mmu_map(pagetable, - device->mmu.dummyspace.physaddr, - device->mmu.dummyspace.size, - GSL_PT_PAGE_RV | GSL_PT_PAGE_WV, &gpuaddr, - KGSL_MEMFLAGS_CONPHYS | KGSL_MEMFLAGS_ALIGN4K); - - if (result) - goto unmap_memstore_desc; - - if (device->mmu.dummyspace.gpuaddr == 0) - device->mmu.dummyspace.gpuaddr = gpuaddr; - BUG_ON(device->mmu.dummyspace.gpuaddr != gpuaddr); - - return result; - -unmap_memstore_desc: - kgsl_mmu_unmap(pagetable, device->memstore.gpuaddr, - device->memstore.size); - -unmap_memptrs_desc: - kgsl_mmu_unmap(pagetable, device->ringbuffer.memptrs_desc.gpuaddr, - device->ringbuffer.memptrs_desc.size); -unmap_buffer_desc: - kgsl_mmu_unmap(pagetable, device->ringbuffer.buffer_desc.gpuaddr, - device->ringbuffer.buffer_desc.size); -error: - return result; - -} - -#ifdef CONFIG_GPU_MSM_KGSL_MMU -int kgsl_yamato_setstate(struct kgsl_device *device, uint32_t flags) -{ - unsigned int link[32]; - unsigned int *cmds = &link[0]; - int sizedwords = 0; - unsigned int mh_mmu_invalidate = 0x00000003; /*invalidate all and tc */ - - KGSL_MEM_DBG("device %p ctxt %p pt %p\n", - device, - device->drawctxt_active, - device->mmu.hwpagetable); - /* if possible, set via command stream, - * otherwise set via direct register writes - */ - if (device->drawctxt_active) { - KGSL_MEM_DBG("cmds\n"); - if (flags & KGSL_MMUFLAGS_PTUPDATE) { - /* wait for graphics pipe to be idle */ - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0x00000000; - - /* set page table base */ - *cmds++ = pm4_type0_packet(REG_MH_MMU_PT_BASE, 1); - *cmds++ = device->mmu.hwpagetable->base.gpuaddr; - sizedwords += 4; - } - - if (flags & KGSL_MMUFLAGS_TLBFLUSH) { - *cmds++ = pm4_type0_packet(REG_MH_MMU_INVALIDATE, 1); - *cmds++ = mh_mmu_invalidate; - sizedwords += 2; - } - - if (flags & KGSL_MMUFLAGS_PTUPDATE) { - /* HW workaround: to resolve MMU page fault interrupts - * caused by the VGT.It prevents the CP PFP from filling - * the VGT DMA request fifo too early,thereby ensuring - * that the VGT will not fetch vertex/bin data until - * after the page table base register has been updated. - * - * Two null DRAW_INDX_BIN packets are inserted right - * after the page table base update, followed by a - * wait for idle. The null packets will fill up the - * VGT DMA request fifo and prevent any further - * vertex/bin updates from occurring until the wait - * has finished. */ - *cmds++ = pm4_type3_packet(PM4_SET_CONSTANT, 2); - *cmds++ = (0x4 << 16) | - (REG_PA_SU_SC_MODE_CNTL - 0x2000); - *cmds++ = 0; /* disable faceness generation */ - *cmds++ = pm4_type3_packet(PM4_SET_BIN_BASE_OFFSET, 1); - *cmds++ = device->mmu.dummyspace.gpuaddr; - *cmds++ = pm4_type3_packet(PM4_DRAW_INDX_BIN, 6); - *cmds++ = 0; /* viz query info */ - *cmds++ = 0x0003C004; /* draw indicator */ - *cmds++ = 0; /* bin base */ - *cmds++ = 3; /* bin size */ - *cmds++ = device->mmu.dummyspace.gpuaddr; /* dma base */ - *cmds++ = 6; /* dma size */ - *cmds++ = pm4_type3_packet(PM4_DRAW_INDX_BIN, 6); - *cmds++ = 0; /* viz query info */ - *cmds++ = 0x0003C004; /* draw indicator */ - *cmds++ = 0; /* bin base */ - *cmds++ = 3; /* bin size */ - /* dma base */ - *cmds++ = device->mmu.dummyspace.gpuaddr; - *cmds++ = 6; /* dma size */ - *cmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1); - *cmds++ = 0x00000000; - sizedwords += 21; - } - - if (flags & (KGSL_MMUFLAGS_PTUPDATE | KGSL_MMUFLAGS_TLBFLUSH)) { - *cmds++ = pm4_type3_packet(PM4_INVALIDATE_STATE, 1); - *cmds++ = 0x7fff; /* invalidate all base pointers */ - sizedwords += 2; - } - - kgsl_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_PMODE, - &link[0], sizedwords); - } else { - KGSL_MEM_DBG("regs\n"); - - if (flags & KGSL_MMUFLAGS_PTUPDATE) { - kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT); - kgsl_yamato_regwrite(device, REG_MH_MMU_PT_BASE, - device->mmu.hwpagetable->base.gpuaddr); - } - - if (flags & KGSL_MMUFLAGS_TLBFLUSH) { - kgsl_yamato_regwrite(device, REG_MH_MMU_INVALIDATE, - mh_mmu_invalidate); - } - } - - return 0; -} -#endif - -static unsigned int -kgsl_yamato_getchipid(struct kgsl_device *device) -{ - unsigned int chipid; - unsigned int coreid, majorid, minorid, patchid, revid; - - /* YDX */ - kgsl_yamato_regread(device, REG_RBBM_PERIPHID1, &coreid); - coreid &= 0xF; - - kgsl_yamato_regread(device, REG_RBBM_PERIPHID2, &majorid); - majorid = (majorid >> 4) & 0xF; - - kgsl_yamato_regread(device, REG_RBBM_PATCH_RELEASE, &revid); - /* this is a 16bit field, but extremely unlikely it would ever get - * this high - */ - minorid = ((revid >> 0) & 0xFF); - - - patchid = ((revid >> 16) & 0xFF); - - chipid = ((coreid << 24) | (majorid << 16) | - (minorid << 8) | (patchid << 0)); - - /* Hardware revision 211 (8650) returns the wrong chip ID */ - if (chipid == KGSL_CHIPID_YAMATODX_REV21) - chipid = KGSL_CHIPID_YAMATODX_REV211; - - return chipid; -} - -int kgsl_yamato_init(struct kgsl_device *device, struct kgsl_devconfig *config) -{ - int status = -EINVAL; - int init_reftimestamp = 0x7fffffff; - struct kgsl_memregion *regspace = &device->regspace; - unsigned int memflags = KGSL_MEMFLAGS_ALIGNPAGE | KGSL_MEMFLAGS_CONPHYS; - - KGSL_DRV_VDBG("enter (device=%p, config=%p)\n", device, config); - - if (device->flags & KGSL_FLAGS_INITIALIZED) { - KGSL_DRV_VDBG("return %d\n", 0); - return 0; - } - memset(device, 0, sizeof(*device)); - - init_waitqueue_head(&device->ib1_wq); - - memcpy(regspace, &config->regspace, sizeof(device->regspace)); - if (regspace->mmio_phys_base == 0 || regspace->sizebytes == 0) { - KGSL_DRV_ERR("dev %d invalid regspace\n", device->id); - goto error; - } - if (!request_mem_region(regspace->mmio_phys_base, - regspace->sizebytes, DRIVER_NAME)) { - KGSL_DRV_ERR("request_mem_region failed for register memory\n"); - status = -ENODEV; - goto error; - } - - regspace->mmio_virt_base = ioremap(regspace->mmio_phys_base, - regspace->sizebytes); - KGSL_MEM_INFO("ioremap(regs) = %p\n", regspace->mmio_virt_base); - if (regspace->mmio_virt_base == NULL) { - KGSL_DRV_ERR("ioremap failed for register memory\n"); - status = -ENODEV; - goto error_release_mem; - } - - KGSL_DRV_INFO("dev %d regs phys 0x%08x size 0x%08x virt %p\n", - device->id, regspace->mmio_phys_base, - regspace->sizebytes, regspace->mmio_virt_base); - - memcpy(&device->gmemspace, &config->gmemspace, - sizeof(device->gmemspace)); - - device->id = KGSL_DEVICE_YAMATO; - - if (config->mmu_config) { - device->mmu.config = config->mmu_config; - device->mmu.mpu_base = config->mpu_base; - device->mmu.mpu_range = config->mpu_range; - device->mmu.va_base = config->va_base; - device->mmu.va_range = config->va_range; - } - - device->chip_id = kgsl_yamato_getchipid(device); - - /*We need to make sure all blocks are powered up and clocked before - *issuing a soft reset. The overrides will be turned off (set to 0) - *later in kgsl_yamato_start. - */ - kgsl_yamato_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0xfffffffe); - kgsl_yamato_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0xffffffff); - - kgsl_yamato_regwrite(device, REG_RBBM_SOFT_RESET, 0xFFFFFFFF); - msleep(50); - kgsl_yamato_regwrite(device, REG_RBBM_SOFT_RESET, 0x00000000); - - kgsl_yamato_regwrite(device, REG_RBBM_CNTL, 0x00004442); - - kgsl_yamato_regwrite(device, REG_MH_ARBITER_CONFIG, - KGSL_CFG_YAMATO_MHARB); - - kgsl_yamato_regwrite(device, REG_SQ_VS_PROGRAM, 0x00000000); - kgsl_yamato_regwrite(device, REG_SQ_PS_PROGRAM, 0x00000000); - - - status = kgsl_mmu_init(device); - if (status != 0) { - status = -ENODEV; - goto error_iounmap; - } - - status = kgsl_cmdstream_init(device); - if (status != 0) { - status = -ENODEV; - goto error_close_mmu; - } - - status = kgsl_sharedmem_alloc(memflags, sizeof(device->memstore), - &device->memstore); - if (status != 0) { - status = -ENODEV; - goto error_close_cmdstream; - } - kgsl_sharedmem_set(&device->memstore, 0, 0, device->memstore.size); - - kgsl_sharedmem_write(&device->memstore, - KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts), - &init_reftimestamp, 4); - - kgsl_yamato_regwrite(device, REG_RBBM_DEBUG, 0x00080000); - pr_info("msm_kgsl: initilized dev=%d mmu=%s\n", device->id, - kgsl_mmu_isenabled(&device->mmu) ? "on" : "off"); - - device->flags |= KGSL_FLAGS_INITIALIZED; - return 0; - -error_close_cmdstream: - kgsl_cmdstream_close(device); -error_close_mmu: - kgsl_mmu_close(device); -error_iounmap: - iounmap(regspace->mmio_virt_base); - regspace->mmio_virt_base = NULL; -error_release_mem: - release_mem_region(regspace->mmio_phys_base, regspace->sizebytes); -error: - return status; -} - -int kgsl_yamato_close(struct kgsl_device *device) -{ - struct kgsl_memregion *regspace = &device->regspace; - - if (device->memstore.hostptr) - kgsl_sharedmem_free(&device->memstore); - - kgsl_mmu_close(device); - - kgsl_cmdstream_close(device); - - if (regspace->mmio_virt_base != NULL) { - KGSL_MEM_INFO("iounmap(regs) = %p\n", regspace->mmio_virt_base); - iounmap(regspace->mmio_virt_base); - regspace->mmio_virt_base = NULL; - release_mem_region(regspace->mmio_phys_base, - regspace->sizebytes); - } - - KGSL_DRV_VDBG("return %d\n", 0); - device->flags &= ~KGSL_FLAGS_INITIALIZED; - return 0; -} - -int kgsl_yamato_start(struct kgsl_device *device, uint32_t flags) -{ - int status = -EINVAL; - - KGSL_DRV_VDBG("enter (device=%p)\n", device); - - if (!(device->flags & KGSL_FLAGS_INITIALIZED)) { - KGSL_DRV_ERR("Trying to start uninitialized device.\n"); - return -EINVAL; - } - - device->refcnt++; - - if (device->flags & KGSL_FLAGS_STARTED) { - KGSL_DRV_VDBG("already started"); - return 0; - } - - kgsl_yamato_regwrite(device, REG_RBBM_PM_OVERRIDE1, 0); - kgsl_yamato_regwrite(device, REG_RBBM_PM_OVERRIDE2, 0); - - KGSL_DRV_DBG("enabling RBBM interrupts mask 0x%08lx\n", - GSL_RBBM_INT_MASK); - kgsl_yamato_regwrite(device, REG_RBBM_INT_CNTL, GSL_RBBM_INT_MASK); - - /* make sure SQ interrupts are disabled */ - kgsl_yamato_regwrite(device, REG_SQ_INT_CNTL, 0); - - kgsl_yamato_gmeminit(device); - - status = kgsl_ringbuffer_init(device); - if (status != 0) { - kgsl_yamato_stop(device); - return status; - } - - status = kgsl_drawctxt_init(device); - if (status != 0) { - kgsl_yamato_stop(device); - return status; - } - - device->flags |= KGSL_FLAGS_STARTED; - - KGSL_DRV_VDBG("return %d\n", status); - return status; -} - -int kgsl_yamato_stop(struct kgsl_device *device) -{ - if (device->flags & KGSL_FLAGS_STARTED) { - - kgsl_yamato_regwrite(device, REG_RBBM_INT_CNTL, 0); - - kgsl_yamato_regwrite(device, REG_SQ_INT_CNTL, 0); - - kgsl_drawctxt_close(device); - - kgsl_ringbuffer_close(&device->ringbuffer); - - kgsl_yamato_gmemclose(device); - - device->flags &= ~KGSL_FLAGS_STARTED; - } - - return 0; -} - -int kgsl_yamato_getproperty(struct kgsl_device *device, - enum kgsl_property_type type, - void *value, - unsigned int sizebytes) -{ - int status = -EINVAL; - - switch (type) { - case KGSL_PROP_DEVICE_INFO: - { - struct kgsl_devinfo devinfo; - - if (sizebytes != sizeof(devinfo)) { - status = -EINVAL; - break; - } - - memset(&devinfo, 0, sizeof(devinfo)); - devinfo.device_id = device->id; - devinfo.chip_id = device->chip_id; - devinfo.mmu_enabled = kgsl_mmu_isenabled(&device->mmu); - devinfo.gmem_hostbaseaddr = - (unsigned int)device->gmemspace.mmio_virt_base; - devinfo.gmem_gpubaseaddr = device->gmemspace.gpu_base; - devinfo.gmem_sizebytes = device->gmemspace.sizebytes; - - if (copy_to_user(value, &devinfo, sizeof(devinfo)) != - 0) { - status = -EFAULT; - break; - } - status = 0; - } - break; - case KGSL_PROP_DEVICE_SHADOW: - { - struct kgsl_shadowprop shadowprop; - - if (sizebytes != sizeof(shadowprop)) { - status = -EINVAL; - break; - } - memset(&shadowprop, 0, sizeof(shadowprop)); - if (device->memstore.hostptr) { - /*NOTE: with mmu enabled, gpuaddr doesn't mean - * anything to mmap(). - */ - shadowprop.gpuaddr = device->memstore.physaddr; - shadowprop.size = device->memstore.size; - shadowprop.flags = KGSL_FLAGS_INITIALIZED; - } - if (copy_to_user(value, &shadowprop, - sizeof(shadowprop))) { - status = -EFAULT; - break; - } - status = 0; - } - break; - case KGSL_PROP_MMU_ENABLE: - { -#ifdef CONFIG_GPU_MSM_KGSL_MMU - int mmuProp = 1; -#else - int mmuProp = 0; -#endif - if (sizebytes != sizeof(int)) { - status = -EINVAL; - break; - } - if (copy_to_user(value, &mmuProp, sizeof(mmuProp))) { - status = -EFAULT; - break; - } - status = 0; - } - break; - case KGSL_PROP_INTERRUPT_WAITS: - { - int int_waits = 1; - if (sizebytes != sizeof(int)) { - status = -EINVAL; - break; - } - if (copy_to_user(value, &int_waits, sizeof(int))) { - status = -EFAULT; - break; - } - status = 0; - } - break; - default: - status = -EINVAL; - } - - return status; -} - -/* Note: This is either called from the standby timer, or while holding the - * driver mutex. - * - * The reader may obseve that this function may be called without holding the - * driver mutex (in the timer), which can cause the ringbuffer write pointer - * to change, when a user submits a command. However, the user must be holding - * the driver mutex when doing so, and then must - * have canceled the timer. If the timer was executing at the time of - * cancellation, the active flag would have been cleared, which the user - * ioctl checks for after cancelling the timer. - */ -bool kgsl_yamato_is_idle(struct kgsl_device *device) -{ - struct kgsl_ringbuffer *rb = &device->ringbuffer; - unsigned int rbbm_status; - - BUG_ON(!(rb->flags & KGSL_FLAGS_STARTED)); - - GSL_RB_GET_READPTR(rb, &rb->rptr); - if (rb->rptr == rb->wptr) { - kgsl_yamato_regread(device, REG_RBBM_STATUS, &rbbm_status); - if (rbbm_status == 0x110) - return true; - } - return false; -} - -int kgsl_yamato_idle(struct kgsl_device *device, unsigned int timeout) -{ - int status = -EINVAL; - struct kgsl_ringbuffer *rb = &device->ringbuffer; - struct kgsl_mmu_debug mmu_dbg; - unsigned int rbbm_status; - int idle_count = 0; -#define IDLE_COUNT_MAX 1000000 - - KGSL_DRV_VDBG("enter (device=%p, timeout=%d)\n", device, timeout); - - (void)timeout; - - /* first, wait until the CP has consumed all the commands in - * the ring buffer - */ - if (rb->flags & KGSL_FLAGS_STARTED) { - do { - idle_count++; - GSL_RB_GET_READPTR(rb, &rb->rptr); - - } while (rb->rptr != rb->wptr && idle_count < IDLE_COUNT_MAX); - if (idle_count == IDLE_COUNT_MAX) - goto err; - } - /* now, wait for the GPU to finish its operations */ - for (idle_count = 0; idle_count < IDLE_COUNT_MAX; idle_count++) { - kgsl_yamato_regread(device, REG_RBBM_STATUS, &rbbm_status); - - if (rbbm_status == 0x110) { - status = 0; - goto done; - } - } - -err: - KGSL_DRV_ERR("spun too long waiting for RB to idle\n"); - kgsl_register_dump(device); - kgsl_ringbuffer_dump(rb); - kgsl_mmu_debug(&device->mmu, &mmu_dbg); - BUG(); - -done: - KGSL_DRV_VDBG("return %d\n", status); - - return status; -} - -int kgsl_yamato_regread(struct kgsl_device *device, unsigned int offsetwords, - unsigned int *value) -{ - unsigned int *reg; - - if (offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes) { - KGSL_DRV_ERR("invalid offset %d\n", offsetwords); - return -ERANGE; - } - - reg = (unsigned int *)(device->regspace.mmio_virt_base - + (offsetwords << 2)); - *value = readl(reg); - - return 0; -} - -int kgsl_yamato_regwrite(struct kgsl_device *device, unsigned int offsetwords, - unsigned int value) -{ - unsigned int *reg; - - if (offsetwords*sizeof(uint32_t) >= device->regspace.sizebytes) { - KGSL_DRV_ERR("invalid offset %d\n", offsetwords); - return -ERANGE; - } - - reg = (unsigned int *)(device->regspace.mmio_virt_base - + (offsetwords << 2)); - writel(value, reg); - - return 0; -} - -static inline int _wait_timestamp(struct kgsl_device *device, - unsigned int timestamp, - unsigned int msecs) -{ - long status; - - status = wait_event_interruptible_timeout(device->ib1_wq, - kgsl_cmdstream_check_timestamp(device, timestamp), - msecs_to_jiffies(msecs)); - - if (status > 0) - status = 0; - else if (status == 0) { - if (!kgsl_cmdstream_check_timestamp(device, timestamp)) { - status = -ETIMEDOUT; - kgsl_register_dump(device); - } - } - - return (int)status; -} - -/* MUST be called with the kgsl_driver.mutex held */ -int kgsl_yamato_waittimestamp(struct kgsl_device *device, - unsigned int timestamp, - unsigned int msecs) -{ - long status = 0; - uint32_t ref_ts; - int enableflag = 1; - unsigned int cmd[2]; - - KGSL_DRV_INFO("enter (device=%p,timestamp=%d,timeout=0x%08x)\n", - device, timestamp, msecs); - - if (!kgsl_cmdstream_check_timestamp(device, timestamp)) { - kgsl_sharedmem_read(&device->memstore, &ref_ts, - KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts), 4); - if (timestamp_cmp(ref_ts, timestamp)) { - kgsl_sharedmem_write(&device->memstore, - KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts), - ×tamp, 4); - } - - cmd[0] = pm4_type3_packet(PM4_INTERRUPT, 1); - cmd[1] = CP_INT_CNTL__IB1_INT_MASK; - kgsl_ringbuffer_issuecmds(device, KGSL_CMD_FLAGS_NO_TS_CMP, - cmd, 2); - kgsl_sharedmem_write(&device->memstore, - KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable), - &enableflag, 4); - - mutex_unlock(&kgsl_driver.mutex); - status = _wait_timestamp(device, timestamp, msecs); - mutex_lock(&kgsl_driver.mutex); - } - - KGSL_DRV_INFO("return %ld\n", status); - return (int)status; -} - -int kgsl_yamato_runpending(struct kgsl_device *device) -{ - if (device->flags & KGSL_FLAGS_INITIALIZED) - kgsl_cmdstream_memqueue_drain(device); - return 0; -} - -int __init kgsl_yamato_config(struct kgsl_devconfig *devconfig, - struct platform_device *pdev) -{ - int result = 0; - struct resource *res = NULL; - - memset(devconfig, 0, sizeof(*devconfig)); - - /*find memory regions */ - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, - "kgsl_reg_memory"); - if (res == NULL) { - KGSL_DRV_ERR("platform_get_resource_byname failed\n"); - result = -EINVAL; - goto done; - } - KGSL_DRV_DBG("registers at %08x to %08x\n", res->start, res->end); - devconfig->regspace.mmio_phys_base = res->start; - devconfig->regspace.sizebytes = resource_size(res); - - devconfig->gmemspace.gpu_base = 0; - devconfig->gmemspace.sizebytes = SZ_256K; - - /*note: for all of these behavior masks: - * 0 = do not translate - * 1 = translate within va_range, otherwise use physical - * 2 = translate within va_range, otherwise fault - */ - devconfig->mmu_config = 1 /* mmu enable */ - | (2 << MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT) - | (2 << MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT); - - /*TODO: these should probably be configurable from platform device - * stuff */ - devconfig->va_base = 0x66000000; - devconfig->va_range = SZ_128M; - - /* turn off memory protection unit by setting acceptable physical - * address range to include all pages. Apparrently MPU causing - * problems. - */ - devconfig->mpu_base = 0x00000000; - devconfig->mpu_range = 0xFFFFF000; - - result = 0; -done: - return result; -} diff --git a/drivers/video/msm/gpu/kgsl/yamato_reg.h b/drivers/video/msm/gpu/kgsl/yamato_reg.h deleted file mode 100644 index 828b95aa..00000000 --- a/drivers/video/msm/gpu/kgsl/yamato_reg.h +++ /dev/null @@ -1,400 +0,0 @@ -/* - * (C) Copyright Advanced Micro Devices, Inc. 2002, 2007 - * Copyright (c) 2008-2009 QUALCOMM USA, INC. - * - * All source code in this file is licensed under the following license - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, you can find it at http://www.fsf.org - */ -#ifndef _YAMATO_REG_H -#define _YAMATO_REG_H - -enum VGT_EVENT_TYPE { - VS_DEALLOC = 0, - PS_DEALLOC = 1, - VS_DONE_TS = 2, - PS_DONE_TS = 3, - CACHE_FLUSH_TS = 4, - CONTEXT_DONE = 5, - CACHE_FLUSH = 6, - VIZQUERY_START = 7, - VIZQUERY_END = 8, - SC_WAIT_WC = 9, - RST_PIX_CNT = 13, - RST_VTX_CNT = 14, - TILE_FLUSH = 15, - CACHE_FLUSH_AND_INV_TS_EVENT = 20, - ZPASS_DONE = 21, - CACHE_FLUSH_AND_INV_EVENT = 22, - PERFCOUNTER_START = 23, - PERFCOUNTER_STOP = 24, - VS_FETCH_DONE = 27, - FACENESS_FLUSH = 28, -}; - -enum COLORFORMATX { - COLORX_4_4_4_4 = 0, - COLORX_1_5_5_5 = 1, - COLORX_5_6_5 = 2, - COLORX_8 = 3, - COLORX_8_8 = 4, - COLORX_8_8_8_8 = 5, - COLORX_S8_8_8_8 = 6, - COLORX_16_FLOAT = 7, - COLORX_16_16_FLOAT = 8, - COLORX_16_16_16_16_FLOAT = 9, - COLORX_32_FLOAT = 10, - COLORX_32_32_FLOAT = 11, - COLORX_32_32_32_32_FLOAT = 12, - COLORX_2_3_3 = 13, - COLORX_8_8_8 = 14, -}; - -enum SURFACEFORMAT { - FMT_1_REVERSE = 0, - FMT_1 = 1, - FMT_8 = 2, - FMT_1_5_5_5 = 3, - FMT_5_6_5 = 4, - FMT_6_5_5 = 5, - FMT_8_8_8_8 = 6, - FMT_2_10_10_10 = 7, - FMT_8_A = 8, - FMT_8_B = 9, - FMT_8_8 = 10, - FMT_Cr_Y1_Cb_Y0 = 11, - FMT_Y1_Cr_Y0_Cb = 12, - FMT_5_5_5_1 = 13, - FMT_8_8_8_8_A = 14, - FMT_4_4_4_4 = 15, - FMT_10_11_11 = 16, - FMT_11_11_10 = 17, - FMT_DXT1 = 18, - FMT_DXT2_3 = 19, - FMT_DXT4_5 = 20, - FMT_24_8 = 22, - FMT_24_8_FLOAT = 23, - FMT_16 = 24, - FMT_16_16 = 25, - FMT_16_16_16_16 = 26, - FMT_16_EXPAND = 27, - FMT_16_16_EXPAND = 28, - FMT_16_16_16_16_EXPAND = 29, - FMT_16_FLOAT = 30, - FMT_16_16_FLOAT = 31, - FMT_16_16_16_16_FLOAT = 32, - FMT_32 = 33, - FMT_32_32 = 34, - FMT_32_32_32_32 = 35, - FMT_32_FLOAT = 36, - FMT_32_32_FLOAT = 37, - FMT_32_32_32_32_FLOAT = 38, - FMT_32_AS_8 = 39, - FMT_32_AS_8_8 = 40, - FMT_16_MPEG = 41, - FMT_16_16_MPEG = 42, - FMT_8_INTERLACED = 43, - FMT_32_AS_8_INTERLACED = 44, - FMT_32_AS_8_8_INTERLACED = 45, - FMT_16_INTERLACED = 46, - FMT_16_MPEG_INTERLACED = 47, - FMT_16_16_MPEG_INTERLACED = 48, - FMT_DXN = 49, - FMT_8_8_8_8_AS_16_16_16_16 = 50, - FMT_DXT1_AS_16_16_16_16 = 51, - FMT_DXT2_3_AS_16_16_16_16 = 52, - FMT_DXT4_5_AS_16_16_16_16 = 53, - FMT_2_10_10_10_AS_16_16_16_16 = 54, - FMT_10_11_11_AS_16_16_16_16 = 55, - FMT_11_11_10_AS_16_16_16_16 = 56, - FMT_32_32_32_FLOAT = 57, - FMT_DXT3A = 58, - FMT_DXT5A = 59, - FMT_CTX1 = 60, - FMT_DXT3A_AS_1_1_1_1 = 61 -}; - -#define RB_EDRAM_INFO_EDRAM_SIZE_SIZE 4 -#define RB_EDRAM_INFO_EDRAM_MAPPING_MODE_SIZE 2 -#define RB_EDRAM_INFO_UNUSED0_SIZE 8 -#define RB_EDRAM_INFO_EDRAM_RANGE_SIZE 18 - -struct rb_edram_info_t { - unsigned int edram_size:RB_EDRAM_INFO_EDRAM_SIZE_SIZE; - unsigned int edram_mapping_mode:RB_EDRAM_INFO_EDRAM_MAPPING_MODE_SIZE; - unsigned int unused0:RB_EDRAM_INFO_UNUSED0_SIZE; - unsigned int edram_range:RB_EDRAM_INFO_EDRAM_RANGE_SIZE; -}; - -union reg_rb_edram_info { - unsigned int val:32; - struct rb_edram_info_t f; -}; - -#define CP_RB_CNTL_RB_BUFSZ_SIZE 6 -#define CP_RB_CNTL_UNUSED0_SIZE 2 -#define CP_RB_CNTL_RB_BLKSZ_SIZE 6 -#define CP_RB_CNTL_UNUSED1_SIZE 2 -#define CP_RB_CNTL_BUF_SWAP_SIZE 2 -#define CP_RB_CNTL_UNUSED2_SIZE 2 -#define CP_RB_CNTL_RB_POLL_EN_SIZE 1 -#define CP_RB_CNTL_UNUSED3_SIZE 6 -#define CP_RB_CNTL_RB_NO_UPDATE_SIZE 1 -#define CP_RB_CNTL_UNUSED4_SIZE 3 -#define CP_RB_CNTL_RB_RPTR_WR_ENA_SIZE 1 - -struct cp_rb_cntl_t { - unsigned int rb_bufsz:CP_RB_CNTL_RB_BUFSZ_SIZE; - unsigned int unused0:CP_RB_CNTL_UNUSED0_SIZE; - unsigned int rb_blksz:CP_RB_CNTL_RB_BLKSZ_SIZE; - unsigned int unused1:CP_RB_CNTL_UNUSED1_SIZE; - unsigned int buf_swap:CP_RB_CNTL_BUF_SWAP_SIZE; - unsigned int unused2:CP_RB_CNTL_UNUSED2_SIZE; - unsigned int rb_poll_en:CP_RB_CNTL_RB_POLL_EN_SIZE; - unsigned int unused3:CP_RB_CNTL_UNUSED3_SIZE; - unsigned int rb_no_update:CP_RB_CNTL_RB_NO_UPDATE_SIZE; - unsigned int unused4:CP_RB_CNTL_UNUSED4_SIZE; - unsigned int rb_rptr_wr_ena:CP_RB_CNTL_RB_RPTR_WR_ENA_SIZE; -}; - -union reg_cp_rb_cntl { - unsigned int val:32; - struct cp_rb_cntl_t f; -}; - -#define RB_COLOR_INFO__COLOR_FORMAT_MASK 0x0000000fL -#define RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT 0x00000004 - - -#define SQ_INT_CNTL__PS_WATCHDOG_MASK 0x00000001L -#define SQ_INT_CNTL__VS_WATCHDOG_MASK 0x00000002L - -#define MH_INTERRUPT_MASK__AXI_READ_ERROR 0x00000001L -#define MH_INTERRUPT_MASK__AXI_WRITE_ERROR 0x00000002L -#define MH_INTERRUPT_MASK__MMU_PAGE_FAULT 0x00000004L - -#define RBBM_INT_CNTL__RDERR_INT_MASK 0x00000001L -#define RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK 0x00000002L -#define RBBM_INT_CNTL__GUI_IDLE_INT_MASK 0x00080000L - -#define RBBM_STATUS__CMDFIFO_AVAIL_MASK 0x0000001fL -#define RBBM_STATUS__TC_BUSY_MASK 0x00000020L -#define RBBM_STATUS__HIRQ_PENDING_MASK 0x00000100L -#define RBBM_STATUS__CPRQ_PENDING_MASK 0x00000200L -#define RBBM_STATUS__CFRQ_PENDING_MASK 0x00000400L -#define RBBM_STATUS__PFRQ_PENDING_MASK 0x00000800L -#define RBBM_STATUS__VGT_BUSY_NO_DMA_MASK 0x00001000L -#define RBBM_STATUS__RBBM_WU_BUSY_MASK 0x00004000L -#define RBBM_STATUS__CP_NRT_BUSY_MASK 0x00010000L -#define RBBM_STATUS__MH_BUSY_MASK 0x00040000L -#define RBBM_STATUS__MH_COHERENCY_BUSY_MASK 0x00080000L -#define RBBM_STATUS__SX_BUSY_MASK 0x00200000L -#define RBBM_STATUS__TPC_BUSY_MASK 0x00400000L -#define RBBM_STATUS__SC_CNTX_BUSY_MASK 0x01000000L -#define RBBM_STATUS__PA_BUSY_MASK 0x02000000L -#define RBBM_STATUS__VGT_BUSY_MASK 0x04000000L -#define RBBM_STATUS__SQ_CNTX17_BUSY_MASK 0x08000000L -#define RBBM_STATUS__SQ_CNTX0_BUSY_MASK 0x10000000L -#define RBBM_STATUS__RB_CNTX_BUSY_MASK 0x40000000L -#define RBBM_STATUS__GUI_ACTIVE_MASK 0x80000000L - -#define CP_INT_CNTL__SW_INT_MASK 0x00080000L -#define CP_INT_CNTL__T0_PACKET_IN_IB_MASK 0x00800000L -#define CP_INT_CNTL__OPCODE_ERROR_MASK 0x01000000L -#define CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK 0x02000000L -#define CP_INT_CNTL__RESERVED_BIT_ERROR_MASK 0x04000000L -#define CP_INT_CNTL__IB_ERROR_MASK 0x08000000L -#define CP_INT_CNTL__IB2_INT_MASK 0x20000000L -#define CP_INT_CNTL__IB1_INT_MASK 0x40000000L -#define CP_INT_CNTL__RB_INT_MASK 0x80000000L - -#define MASTER_INT_SIGNAL__MH_INT_STAT 0x00000020L -#define MASTER_INT_SIGNAL__SQ_INT_STAT 0x04000000L -#define MASTER_INT_SIGNAL__CP_INT_STAT 0x40000000L -#define MASTER_INT_SIGNAL__RBBM_INT_STAT 0x80000000L - -#define RB_EDRAM_INFO__EDRAM_SIZE_MASK 0x0000000fL -#define RB_EDRAM_INFO__EDRAM_RANGE_MASK 0xffffc000L - -#define MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT 0x00000006 -#define MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT 0x00000007 -#define MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT 0x00000008 -#define MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT 0x00000009 -#define MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT 0x0000000a -#define MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT 0x0000000d -#define MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT 0x0000000e -#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT 0x0000000f -#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT 0x00000010 -#define MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT 0x00000016 -#define MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT 0x00000017 -#define MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT 0x00000018 -#define MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT 0x00000019 -#define MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT 0x0000001a - -#define MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT 0x00000004 -#define MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT 0x00000006 -#define MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT 0x00000008 -#define MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT 0x0000000a -#define MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT 0x0000000c -#define MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT 0x0000000e -#define MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT 0x00000010 -#define MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT 0x00000012 -#define MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT 0x00000014 -#define MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT 0x00000016 -#define MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT 0x00000018 - -#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0x00000000 -#define CP_RB_CNTL__RB_BLKSZ__SHIFT 0x00000008 -#define CP_RB_CNTL__RB_POLL_EN__SHIFT 0x00000014 -#define CP_RB_CNTL__RB_NO_UPDATE__SHIFT 0x0000001b - -#define RB_COLOR_INFO__COLOR_FORMAT__SHIFT 0x00000000 -#define RB_EDRAM_INFO__EDRAM_MAPPING_MODE__SHIFT 0x00000004 -#define RB_EDRAM_INFO__EDRAM_RANGE__SHIFT 0x0000000e - -#define REG_CP_CSQ_IB1_STAT 0x01FE -#define REG_CP_CSQ_IB2_STAT 0x01FF -#define REG_CP_CSQ_RB_STAT 0x01FD -#define REG_CP_DEBUG 0x01FC -#define REG_CP_IB1_BASE 0x0458 -#define REG_CP_IB1_BUFSZ 0x0459 -#define REG_CP_IB2_BASE 0x045A -#define REG_CP_IB2_BUFSZ 0x045B -#define REG_CP_INT_ACK 0x01F4 -#define REG_CP_INT_CNTL 0x01F2 -#define REG_CP_INT_STATUS 0x01F3 -#define REG_CP_ME_CNTL 0x01F6 -#define REG_CP_ME_RAM_DATA 0x01FA -#define REG_CP_ME_RAM_WADDR 0x01F8 -#define REG_CP_ME_STATUS 0x01F7 -#define REG_CP_PFP_UCODE_ADDR 0x00C0 -#define REG_CP_PFP_UCODE_DATA 0x00C1 -#define REG_CP_QUEUE_THRESHOLDS 0x01D5 -#define REG_CP_RB_BASE 0x01C0 -#define REG_CP_RB_CNTL 0x01C1 -#define REG_CP_RB_RPTR 0x01C4 -#define REG_CP_RB_RPTR_ADDR 0x01C3 -#define REG_CP_RB_RPTR_WR 0x01C7 -#define REG_CP_RB_WPTR 0x01C5 -#define REG_CP_RB_WPTR_BASE 0x01C8 -#define REG_CP_RB_WPTR_DELAY 0x01C6 -#define REG_CP_STAT 0x047F -#define REG_CP_STATE_DEBUG_DATA 0x01ED -#define REG_CP_STATE_DEBUG_INDEX 0x01EC -#define REG_CP_ST_BASE 0x044D -#define REG_CP_ST_BUFSZ 0x044E - -#define REG_MASTER_INT_SIGNAL 0x03B7 - -#define REG_MH_ARBITER_CONFIG 0x0A40 -#define REG_MH_INTERRUPT_CLEAR 0x0A44 -#define REG_MH_INTERRUPT_MASK 0x0A42 -#define REG_MH_INTERRUPT_STATUS 0x0A43 -#define REG_MH_MMU_CONFIG 0x0040 -#define REG_MH_MMU_INVALIDATE 0x0045 -#define REG_MH_MMU_MPU_BASE 0x0046 -#define REG_MH_MMU_MPU_END 0x0047 -#define REG_MH_MMU_PAGE_FAULT 0x0043 -#define REG_MH_MMU_PT_BASE 0x0042 -#define REG_MH_MMU_TRAN_ERROR 0x0044 -#define REG_MH_MMU_VA_RANGE 0x0041 - -#define REG_PA_CL_VPORT_XSCALE 0x210F -#define REG_PA_CL_VPORT_ZOFFSET 0x2114 -#define REG_PA_CL_VPORT_ZSCALE 0x2113 -#define REG_PA_CL_VTE_CNTL 0x2206 -#define REG_PA_SC_AA_MASK 0x2312 -#define REG_PA_SC_LINE_CNTL 0x2300 -#define REG_PA_SC_SCREEN_SCISSOR_BR 0x200F -#define REG_PA_SC_SCREEN_SCISSOR_TL 0x200E -#define REG_PA_SC_VIZ_QUERY 0x2293 -#define REG_PA_SC_VIZ_QUERY_STATUS 0x0C44 -#define REG_PA_SC_WINDOW_OFFSET 0x2080 -#define REG_PA_SC_WINDOW_SCISSOR_BR 0x2082 -#define REG_PA_SC_WINDOW_SCISSOR_TL 0x2081 -#define REG_PA_SU_FACE_DATA 0x0C86 -#define REG_PA_SU_POINT_SIZE 0x2280 -#define REG_PA_SU_POLY_OFFSET_BACK_OFFSET 0x2383 -#define REG_PA_SU_POLY_OFFSET_FRONT_SCALE 0x2380 -#define REG_PA_SU_SC_MODE_CNTL 0x2205 - -#define REG_RBBM_CNTL 0x003B -#define REG_RBBM_INT_ACK 0x03B6 -#define REG_RBBM_INT_CNTL 0x03B4 -#define REG_RBBM_INT_STATUS 0x03B5 -#define REG_RBBM_PATCH_RELEASE 0x0001 -#define REG_RBBM_PERIPHID1 0x03F9 -#define REG_RBBM_PERIPHID2 0x03FA -#define REG_RBBM_DEBUG 0x039B -#define REG_RBBM_PM_OVERRIDE1 0x039C -#define REG_RBBM_PM_OVERRIDE2 0x039D -#define REG_RBBM_READ_ERROR 0x03B3 -#define REG_RBBM_SOFT_RESET 0x003C -#define REG_RBBM_STATUS 0x05D0 - -#define REG_RB_COLORCONTROL 0x2202 -#define REG_RB_COLOR_DEST_MASK 0x2326 -#define REG_RB_COLOR_MASK 0x2104 -#define REG_RB_COPY_CONTROL 0x2318 -#define REG_RB_DEPTHCONTROL 0x2200 -#define REG_RB_EDRAM_INFO 0x0F02 -#define REG_RB_MODECONTROL 0x2208 -#define REG_RB_SURFACE_INFO 0x2000 - -#define REG_SCRATCH_ADDR 0x01DD -#define REG_SCRATCH_REG0 0x0578 -#define REG_SCRATCH_REG2 0x057A -#define REG_SCRATCH_UMSK 0x01DC - -#define REG_SQ_CF_BOOLEANS 0x4900 -#define REG_SQ_CF_LOOP 0x4908 -#define REG_SQ_GPR_MANAGEMENT 0x0D00 -#define REG_SQ_INST_STORE_MANAGMENT 0x0D02 -#define REG_SQ_INT_ACK 0x0D36 -#define REG_SQ_INT_CNTL 0x0D34 -#define REG_SQ_INT_STATUS 0x0D35 -#define REG_SQ_PROGRAM_CNTL 0x2180 -#define REG_SQ_PS_PROGRAM 0x21F6 -#define REG_SQ_VS_PROGRAM 0x21F7 -#define REG_SQ_WRAPPING_0 0x2183 -#define REG_SQ_WRAPPING_1 0x2184 - -#define REG_VGT_ENHANCE 0x2294 -#define REG_VGT_INDX_OFFSET 0x2102 -#define REG_VGT_MAX_VTX_INDX 0x2100 -#define REG_VGT_MIN_VTX_INDX 0x2101 - -#define REG_TP0_CHICKEN 0x0E1E -#define REG_TC_CNTL_STATUS 0x0E00 -#define REG_PA_SC_AA_CONFIG 0x2301 -#define REG_VGT_VERTEX_REUSE_BLOCK_CNTL 0x2316 -#define REG_SQ_INTERPOLATOR_CNTL 0x2182 -#define REG_RB_DEPTH_INFO 0x2002 -#define REG_COHER_DEST_BASE_0 0x2006 -#define REG_PA_SC_SCREEN_SCISSOR_BR 0x200F -#define REG_RB_FOG_COLOR 0x2109 -#define REG_RB_STENCILREFMASK_BF 0x210C -#define REG_PA_SC_LINE_STIPPLE 0x2283 -#define REG_SQ_PS_CONST 0x2308 -#define REG_VGT_VERTEX_REUSE_BLOCK_CNTL 0x2316 -#define REG_RB_DEPTH_CLEAR 0x231D -#define REG_RB_SAMPLE_COUNT_CTL 0x2324 -#define REG_SQ_CONSTANT_0 0x4000 -#define REG_SQ_FETCH_0 0x4800 - -#define REG_MH_AXI_ERROR 0xA45 -#define REG_COHER_BASE_PM4 0xA2A -#define REG_COHER_STATUS_PM4 0xA2B -#define REG_COHER_SIZE_PM4 0xA29 - -#endif /* _YAMATO_REG_H */ From c85abf52721d636d3fa494ad71b8b3e05e072508 Mon Sep 17 00:00:00 2001 From: Shantanu Gupta Date: Thu, 3 May 2012 12:15:59 +0530 Subject: [PATCH 2/6] [MSM] Fix makefile, which in an erroneous manner includes the logo file disregarding the board config --- drivers/video/msm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile index 60380b65..b7380f17 100644 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -1,7 +1,7 @@ # core framebuffer # -obj-y := msm_fb.o logo.o +obj-y := msm_fb.o ifeq ($(CONFIG_FB_MSM_LOGO),y) obj-y += logo.o endif From bffda154f5b16de62761194badbbe8659202c382 Mon Sep 17 00:00:00 2001 From: Shantanu Gupta Date: Thu, 3 May 2012 12:28:28 +0530 Subject: [PATCH 3/6] Cleanup remenant code of older kgsl --- drivers/video/msm/Kconfig | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig index c6610107..5f445724 100644 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -26,17 +26,6 @@ config FB_MSM_DTV bool default n -config GPU_MSM_KGSL - tristate "MSM 3D Graphics driver for QSD8x50 and MSM7x27" - default n - depends on FB_MSM && (ARCH_QSD8X50 || ARCH_MSM7227 || ARCH_MSM7X30) - select GENERIC_ALLOCATOR - select CONFIG_FW_LOADER - help - 3D graphics driver for QSD8x50 and MSM7x27. Required to - use hardware accelerated OpenGL ES 2.0 and 1.1 on these - chips. - config MSM_ROTATOR tristate "MSM Offline Image Rotator Driver" depends on ARCH_MSM7X30 && ANDROID_PMEM From 48322595f912cfb955ed837abb34fc8aeae456bd Mon Sep 17 00:00:00 2001 From: Shantanu Gupta Date: Thu, 3 May 2012 18:49:51 +0530 Subject: [PATCH 4/6] [MSM] Backported a lot of stuff from 2.6.35 and 2.6.32.59 kernels, compiles and tested on device --- arch/arm/configs/htcleo_defconfig | 1 + arch/arm/kernel/entry-common.S | 2 + arch/arm/kernel/head.S | 6 +- arch/arm/mach-msm/acpuclock-scorpion.c | 218 +++---- arch/arm/mach-msm/board-htcleo-audio.c | 1 + arch/arm/mach-msm/board-htcleo-bl-led.c | 1 - arch/arm/mach-msm/board-htcleo-ls.c | 2 +- arch/arm/mach-msm/board-htcleo-mmc.c | 3 +- arch/arm/mach-msm/board-htcleo.c | 51 +- arch/arm/mach-msm/board-htcleo.h | 10 +- arch/arm/mach-msm/clock-wince.c | 30 +- arch/arm/mach-msm/clock.c | 1 + arch/arm/mach-msm/cpufreq.c | 7 + arch/arm/mach-msm/dma.c | 3 +- .../include/mach/board-htcleo-audio.h | 29 + .../include/mach/board-htcleo-microp.h | 10 + .../mach-msm/include/mach/board-htcleo-mmc.h | 31 + arch/arm/mach-msm/include/mach/board.h | 2 + arch/arm/mach-msm/include/mach/camera.h | 1 + arch/arm/mach-msm/include/mach/clk.h | 3 + arch/arm/mach-msm/include/mach/debug_mm.h | 47 ++ arch/arm/mach-msm/include/mach/dma.h | 3 +- arch/arm/mach-msm/include/mach/irqs.h | 1 + arch/arm/mach-msm/include/mach/msm_fb.h | 12 +- .../include/mach/msm_qdsp6_audio_1550.h | 10 +- .../arm/mach-msm/include/mach/msm_rpcrouter.h | 20 +- arch/arm/mach-msm/include/mach/msm_smd.h | 2 + arch/arm/mach-msm/pm.c | 24 +- arch/arm/mach-msm/pwrtest.c | 1 + arch/arm/mach-msm/qdsp6_1550/aac_in.c | 583 +++++++++++++----- arch/arm/mach-msm/qdsp6_1550/audio_ctl.c | 29 +- arch/arm/mach-msm/qdsp6_1550/dal.c | 1 + arch/arm/mach-msm/qdsp6_1550/mp3.c | 1 + arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c | 1 + arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c | 3 +- arch/arm/mach-msm/qdsp6_1550/pcm_in.c | 1 + arch/arm/mach-msm/qdsp6_1550/pcm_out.c | 7 + arch/arm/mach-msm/qdsp6_1550/q6audio.c | 172 +++--- arch/arm/mach-msm/qdsp6_1550/qcelp_in.c | 1 + arch/arm/mach-msm/sirc.c | 6 + arch/arm/mach-msm/smd.c | 29 +- arch/arm/mach-msm/smd_private.h | 27 + arch/arm/mach-msm/smd_rpcrouter.c | 199 +++--- arch/arm/mach-msm/smd_rpcrouter.h | 25 +- arch/arm/mach-msm/smd_rpcrouter_device.c | 1 + arch/arm/mach-msm/smd_rpcrouter_servers.c | 1 + arch/arm/mach-msm/smd_rpcrouter_xdr.c | 8 +- arch/arm/mach-msm/smd_tty.c | 4 + arch/arm/mach-msm/timer.c | 19 +- drivers/misc/pmem.c | 2 +- drivers/mtd/devices/htcleo_nand.c | 32 +- drivers/video/fbmem.c | 121 ++-- drivers/video/msm/Kconfig | 75 ++- drivers/video/msm/Makefile | 7 +- drivers/video/msm/mddi.c | 50 +- drivers/video/msm/mddi_client_dummy.c | 97 --- drivers/video/msm/mddi_client_epson.c | 2 + drivers/video/msm/mddi_client_novb9f6_5582.c | 3 +- drivers/video/msm/mddi_client_nt35399.c | 1 + drivers/video/msm/mddi_client_simple.c | 236 +++++++ drivers/video/msm/mddi_client_toshiba.c | 1 + drivers/video/msm/mddi_hw.h | 9 +- drivers/video/msm/mdp.c | 579 ++++++----------- drivers/video/msm/mdp_hw.h | 107 +++- drivers/video/msm/mdp_hw_legacy.c | 242 ++++++++ drivers/video/msm/mdp_lcdc.c | 334 +++++++--- drivers/video/msm/mdp_ppp.c | 444 ++++++------- drivers/video/msm/mdp_ppp.h | 84 ++- drivers/video/msm/mdp_ppp22.c | 60 +- drivers/video/msm/mdp_ppp31.c | 309 +++++++++- drivers/video/msm/msm_fb.c | 276 ++++++--- include/linux/fb.h | 141 ++++- include/linux/msm_audio_1550.h | 209 +++++++ include/linux/msm_audio_aac.h | 91 +++ include/linux/msm_mdp.h | 106 +--- 75 files changed, 3506 insertions(+), 1762 deletions(-) create mode 100644 arch/arm/mach-msm/include/mach/board-htcleo-audio.h create mode 100644 arch/arm/mach-msm/include/mach/board-htcleo-mmc.h create mode 100644 arch/arm/mach-msm/include/mach/debug_mm.h mode change 100644 => 100755 drivers/misc/pmem.c mode change 100644 => 100755 drivers/video/msm/Kconfig mode change 100644 => 100755 drivers/video/msm/Makefile delete mode 100644 drivers/video/msm/mddi_client_dummy.c create mode 100644 drivers/video/msm/mddi_client_simple.c create mode 100644 drivers/video/msm/mdp_hw_legacy.c create mode 100644 include/linux/msm_audio_1550.h create mode 100644 include/linux/msm_audio_aac.h diff --git a/arch/arm/configs/htcleo_defconfig b/arch/arm/configs/htcleo_defconfig index 5f799b34..830ca0a3 100644 --- a/arch/arm/configs/htcleo_defconfig +++ b/arch/arm/configs/htcleo_defconfig @@ -404,6 +404,7 @@ CONFIG_HAVE_MLOCKED_PAGE_BIT=y CONFIG_KSM=y CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 CONFIG_ALIGNMENT_TRAP=y +CONFIG_ALLOW_CPU_ALIGNMENT=y # CONFIG_UACCESS_WITH_MEMCPY is not set # diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 2c1db77d..a6c66f59 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -382,11 +382,13 @@ ENDPROC(sys_clone_wrapper) sys_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_sigreturn ENDPROC(sys_sigreturn_wrapper) sys_rt_sigreturn_wrapper: add r0, sp, #S_OFF + mov why, #0 @ prevent syscall restart handling b sys_rt_sigreturn ENDPROC(sys_rt_sigreturn_wrapper) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 4946c727..772c3c5b 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -158,10 +158,10 @@ __secondary_data: * registers. */ __enable_mmu: -#ifdef CONFIG_ALIGNMENT_TRAP - orr r0, r0, #CR_A -#else +#ifdef CONFIG_ALLOW_CPU_ALIGNMENT bic r0, r0, #CR_A +#else + orr r0, r0, #CR_A #endif #ifdef CONFIG_CPU_DCACHE_DISABLE bic r0, r0, #CR_C diff --git a/arch/arm/mach-msm/acpuclock-scorpion.c b/arch/arm/mach-msm/acpuclock-scorpion.c index 7aab81e8..e84cbee6 100644 --- a/arch/arm/mach-msm/acpuclock-scorpion.c +++ b/arch/arm/mach-msm/acpuclock-scorpion.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -62,6 +63,19 @@ struct clkctl_acpu_speed { unsigned axiclk_khz; }; +static unsigned long max_axi_rate; + +struct regulator { + struct device *dev; + struct list_head list; + int uA_load; + int min_uV; + int max_uV; + char *supply_name; + struct device_attribute dev_attr; + struct regulator_dev *rdev; +}; + /* clock sources */ #define CLK_TCXO 0 /* 19.2 MHz */ #define CLK_GLOBAL_PLL 1 /* 768 MHz */ @@ -76,135 +90,46 @@ struct clkctl_acpu_speed { #define SRC_PLL1 3 /* 768 MHz */ struct clkctl_acpu_speed acpu_freq_tbl[] = { -#ifdef CONFIG_HTCLEO_UNDERVOLT_1000 - { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1000, 14000 }, + { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1000, 14000}, + { 96000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1000, 14000 }, { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1000, 14000 }, { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 1000, 29000 }, - //{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1000, 29000 }, - { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1000, 58000 }, - { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1000, 117000 }, - { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 }, - { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1025, 117000 }, - { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 }, - { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 }, - { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 }, - { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 }, - { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 }, - { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 }, - { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 }, - { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 }, - { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1200, 128000 }, - { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1200, 128000 }, - { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1225, 128000 }, - { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1225, 128000 }, - { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1225, 128000 }, -#elif CONFIG_HTCLEO_UNDERVOLT_925 - // should work with most of HD2s - { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 925, 14000 }, - { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 925, 14000 }, - { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 925, 29000 }, - //{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 925, 29000 }, - { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 950, 58000 }, - { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 975, 117000 }, - { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 }, - { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1025, 117000 }, - { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 }, - { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 }, - { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 }, - { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 }, - { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 }, - { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 }, - { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 }, - { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 }, - { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1200, 128000 }, - { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1200, 128000 }, - { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1225, 128000 }, - { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1225, 128000 }, - { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1225, 128000 }, -#elif CONFIG_HTCLEO_UNDERVOLT_800 - // not working yet - { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 850, 14000 }, - { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 850, 14000 }, - { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 850, 29000 }, - //{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 850, 29000 }, - { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 850, 58000 }, - { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 875, 117000 }, - { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 900, 117000 }, - { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 925, 117000 }, - { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 950, 117000 }, - { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 950, 117000 }, - { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 975, 117000 }, - { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1000, 117000 }, - { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1025, 117000 }, - { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1050, 117000 }, - { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1125, 128000 }, - { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1125, 128000 }, - { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1150, 128000 }, - { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1150, 128000 }, - { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1175, 128000 }, - { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1175, 128000 }, - { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1200, 128000 }, -#else - { 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1050, 14000}, - { 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1050, 14000 }, - { 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 1050, 29000 }, - /* Work arround for acpu resume hung, GPLL is turn off by arm9 */ - /*{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1050, 29000 },*/ - { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1050, 58000 }, - { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1050, 117000 }, - { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1050, 117000 }, - { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1075, 117000 }, - { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1100, 117000 }, - { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1100, 117000 }, - { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1125, 117000 }, - { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1150, 117000 }, - { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1175, 117000 }, - { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1200, 117000 }, - { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1200, 128000 }, - { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1225, 128000 }, - { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1250, 128000 }, - { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1275, 128000 }, - { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1300, 128000 }, - { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1300, 128000 }, - { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1300, 128000 }, -#endif -#ifdef CONFIG_HTCLEO_OVERCLOCK -#ifdef CONFIG_HTCLEO_UNDERVOLT_1000 - { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 }, - { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 }, - { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 }, - { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 }, - { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 }, -#elif CONFIG_HTCLEO_UNDERVOLT_925 - { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 }, - { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 }, - { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 }, - { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 }, - { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 }, -#elif CONFIG_HTCLEO_UNDERVOLT_800 - { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 }, - { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 }, - { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 }, - { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 }, - { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 }, -#else - { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1300, 128000 }, - { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1300, 128000 }, - { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1300, 128000 }, - { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1325, 128000 }, - { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 }, -#endif + /* Work arround for acpu resume hung, GPLL is turn off by arm9 */ + /*{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1050, 29000 },*/ + { 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1000, 58000 }, + { 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1000, 117000 }, + { 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 }, + { 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1050, 117000 }, + { 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 }, + { 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 }, + { 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 }, + { 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 }, + { 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 }, + { 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 }, + { 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 }, + { 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 }, + { 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1225, 128000 }, + { 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1250, 128000 }, + { 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1300, 128000 }, + { 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1300, 128000 }, + { 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1300, 128000 }, +#ifdef CONFIG_HTCLEO_OVERCLOCK + { 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1300, 128000 }, + { 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1300, 128000 }, + { 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1300, 128000 }, + { 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 }, + { 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 }, #endif #ifdef CONFIG_HTCLEO_EXOVERCLOCK - { 1228800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x20, 0, 1325, 128000 }, - { 1267200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x21, 0, 1350, 128000 }, - { 1305600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x22, 0, 1350, 128000 }, - { 1344000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x23, 0, 1350, 128000 }, - { 1382400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x24, 0, 1350, 128000 }, - { 1420800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x25, 0, 1350, 128000 }, - { 1459200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x26, 0, 1350, 128000 }, - { 1497600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x27, 0, 1350, 128000 }, - { 1536000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x28, 0, 1350, 128000 }, + { 1228800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x20, 0, 1325, 128000 }, + { 1267200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x21, 0, 1350, 128000 }, + { 1305600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x22, 0, 1350, 128000 }, + { 1344000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x23, 0, 1350, 128000 }, + { 1382400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x24, 0, 1350, 128000 }, + { 1420800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x25, 0, 1350, 128000 }, + { 1459200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x26, 0, 1350, 128000 }, + { 1497600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x27, 0, 1350, 128000 }, + { 1536000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x28, 0, 1350, 128000 }, #endif { 0 }, }; @@ -231,11 +156,10 @@ static void __init acpuclk_init_cpufreq_table(void) freq_table[i].index = i; freq_table[i].frequency = CPUFREQ_ENTRY_INVALID; - /* Skip speeds we don't want */ - if ( acpu_freq_tbl[i].acpu_khz == 19200 || - //acpu_freq_tbl[i].acpu_khz == 128000 || - acpu_freq_tbl[i].acpu_khz == 256000) - continue; + /* Skip speeds using the global pll */ + if (acpu_freq_tbl[i].acpu_khz == 256000 || + acpu_freq_tbl[i].acpu_khz == 19200) + continue; vdd = acpu_freq_tbl[i].vdd; /* Allow mpll and the first scpll speeds */ @@ -269,6 +193,7 @@ struct clock_state { unsigned long wait_for_irq_khz; struct clk* clk_ebi1; struct regulator *regulator; + int (*acpu_set_vdd) (int mvolts); }; static struct clock_state drv_state = { 0 }; @@ -345,11 +270,10 @@ static void scpll_set_freq(uint32_t lval) dmb(); /* wait for frequency switch to finish */ - while (readl(SCPLL_STATUS_ADDR) & 0x1) - ; + while (readl(SCPLL_STATUS_ADDR) & 0x1); /* completion bit is not reliable for SHOT switch */ - udelay(25); + udelay(15); } /* write the new L val and switch mode */ @@ -363,8 +287,7 @@ static void scpll_set_freq(uint32_t lval) dmb(); /* wait for frequency switch to finish */ - while (readl(SCPLL_STATUS_ADDR) & 0x1) - ; + while (readl(SCPLL_STATUS_ADDR) & 0x1); } /* this is still a bit weird... */ @@ -625,13 +548,20 @@ static void __init acpuclk_init(void) } drv_state.current_speed = speed; - for (speed = acpu_freq_tbl; speed->acpu_khz; speed++) + for (speed = acpu_freq_tbl; speed->acpu_khz; speed++) { speed->lpj = cpufreq_scale(loops_per_jiffy, init_khz, speed->acpu_khz); + max_axi_rate = speed->axiclk_khz * 1000; + } loops_per_jiffy = drv_state.current_speed->lpj; } +unsigned long acpuclk_get_max_axi_rate(void) +{ + return max_axi_rate; +} + unsigned long acpuclk_get_rate(void) { return drv_state.current_speed->acpu_khz; @@ -674,6 +604,7 @@ void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata) drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us; drv_state.power_collapse_khz = clkdata->power_collapse_khz; drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz; + drv_state.acpu_set_vdd = acpuclk_set_vdd_level; if (clkdata->mpll_khz) acpu_mpll->acpu_khz = clkdata->mpll_khz; @@ -708,7 +639,7 @@ ssize_t acpuclk_get_vdd_levels_str(char *buf) void acpuclk_set_vdd(unsigned acpu_khz, int vdd) { int i; - vdd = vdd / 25 * 25; //! regulator only accepts multiples of 25 (mV) + vdd = (vdd / HTCLEO_TPS65023_UV_STEP_MV) * HTCLEO_TPS65023_UV_STEP_MV; mutex_lock(&drv_state.lock); for (i = 0; acpu_freq_tbl[i].acpu_khz; i++) { @@ -722,5 +653,16 @@ void acpuclk_set_vdd(unsigned acpu_khz, int vdd) } mutex_unlock(&drv_state.lock); } - +unsigned int acpuclk_get_vdd_min(void) +{ + return HTCLEO_TPS65023_MIN_UV_MV; +} +unsigned int acpuclk_get_vdd_max(void) +{ + return HTCLEO_TPS65023_MAX_UV_MV; +} +unsigned int acpuclk_get_vdd_step(void) +{ + return HTCLEO_TPS65023_UV_STEP_MV; +} #endif diff --git a/arch/arm/mach-msm/board-htcleo-audio.c b/arch/arm/mach-msm/board-htcleo-audio.c index 3b2e66c7..1ee46c6d 100644 --- a/arch/arm/mach-msm/board-htcleo-audio.c +++ b/arch/arm/mach-msm/board-htcleo-audio.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "board-htcleo.h" #include "devices.h" diff --git a/arch/arm/mach-msm/board-htcleo-bl-led.c b/arch/arm/mach-msm/board-htcleo-bl-led.c index 38ec9940..299a8bfa 100644 --- a/arch/arm/mach-msm/board-htcleo-bl-led.c +++ b/arch/arm/mach-msm/board-htcleo-bl-led.c @@ -39,7 +39,6 @@ #define HTCLEO_DEFAULT_BACKLIGHT_BRIGHTNESS 255 - static struct led_trigger *htcleo_lcd_backlight; static int auto_bl_state=0; static DEFINE_MUTEX(htcleo_backlight_lock); diff --git a/arch/arm/mach-msm/board-htcleo-ls.c b/arch/arm/mach-msm/board-htcleo-ls.c index 6583b2ee..8e00c0ef 100644 --- a/arch/arm/mach-msm/board-htcleo-ls.c +++ b/arch/arm/mach-msm/board-htcleo-ls.c @@ -118,7 +118,7 @@ int lightsensor_read_value(uint32_t *val) } *val = data[1] | (data[0] << 8); - D("lsensor adc = %d\n", *val); + D("lsensor adc = %u\n", *val); /* val is unsigned */ return 0; } diff --git a/arch/arm/mach-msm/board-htcleo-mmc.c b/arch/arm/mach-msm/board-htcleo-mmc.c index a4f78f0c..e144e491 100644 --- a/arch/arm/mach-msm/board-htcleo-mmc.c +++ b/arch/arm/mach-msm/board-htcleo-mmc.c @@ -30,6 +30,7 @@ #include #include +#include #include "board-htcleo.h" #include "devices.h" @@ -391,7 +392,7 @@ static int __init htcleommc_dbg_init(void) { struct dentry *dent; - if (!machine_is_htcleo() && !machine_is_htcleo()) + if (!machine_is_htcleo()) return 0; dent = debugfs_create_dir("htcleo_mmc_dbg", 0); diff --git a/arch/arm/mach-msm/board-htcleo.c b/arch/arm/mach-msm/board-htcleo.c index 8b5f90be..01d66fac 100644 --- a/arch/arm/mach-msm/board-htcleo.c +++ b/arch/arm/mach-msm/board-htcleo.c @@ -55,7 +55,9 @@ #ifdef CONFIG_SERIAL_BCM_BT_LPM #include #endif +#ifdef CONFIG_PERFLOCK #include +#endif #include #include @@ -395,10 +397,9 @@ static uint32_t flashlight_gpio_table[] = PCOM_GPIO_CFG(HTCLEO_GPIO_FLASHLIGHT_FLASH, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA), }; -static int config_htcleo_flashlight_gpios(void) +static void config_htcleo_flashlight_gpios(void) { config_gpio_table(flashlight_gpio_table, ARRAY_SIZE(flashlight_gpio_table)); - return 0; } static struct flashlight_platform_data htcleo_flashlight_data = @@ -748,28 +749,6 @@ static struct platform_device qsd_device_spi = { /////////////////////////////////////////////////////////////////////// // KGSL (HW3D support)#include /////////////////////////////////////////////////////////////////////// - -static struct resource msm_kgsl_resources[] = -{ - { - .name = "kgsl_reg_memory", - .start = MSM_GPU_REG_PHYS, - .end = MSM_GPU_REG_PHYS + MSM_GPU_REG_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "kgsl_phys_memory", - .start = MSM_GPU_PHYS_BASE, - .end = MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - { - .start = INT_GRAPHICS, - .end = INT_GRAPHICS, - .flags = IORESOURCE_IRQ, - }, -}; - static int htcleo_kgsl_power_rail_mode(int follow_clk) { int mode = follow_clk ? 0 : 1; @@ -786,16 +765,7 @@ static int htcleo_kgsl_power(bool on) return msm_proc_comm(cmd, &rail_id, 0); } -static struct platform_device msm_kgsl_device = -{ - .name = "kgsl", - .id = -1, - .resource = msm_kgsl_resources, - .num_resources = ARRAY_SIZE(msm_kgsl_resources), -}; - -#ifdef CONFIG_MSM_KGSL -/* start kgsl */ +/* start kgsl-3d0 */ static struct resource kgsl_3d0_resources[] = { { .name = KGSL_3D0_REG_MEMORY, @@ -843,9 +813,7 @@ struct platform_device msm_kgsl_3d0 = { .platform_data = &kgsl_3d0_pdata, }, }; -/* end kgsl */ -#endif - +/* end kgsl-3d0 */ /////////////////////////////////////////////////////////////////////// // Memory /////////////////////////////////////////////////////////////////////// @@ -897,7 +865,7 @@ static struct platform_device android_pmem_mdp_device = { static struct platform_device android_pmem_adsp_device = { .name = "android_pmem", - .id = 4, + .id = 1, /* 4 */ .dev = { .platform_data = &android_pmem_adsp_pdata, }, @@ -905,7 +873,7 @@ static struct platform_device android_pmem_adsp_device = { static struct platform_device android_pmem_venc_device = { .name = "android_pmem", - .id = 5, + .id = 3, /* 5 */ .dev = { .platform_data = &android_pmem_venc_pdata, }, @@ -1083,6 +1051,7 @@ static struct msm_acpu_clock_platform_data htcleo_clock_data = { // .wait_for_irq_khz = 19200, // TCXO }; +#ifdef CONFIG_PERFLOCK static unsigned htcleo_perf_acpu_table[] = { 245000000, 576000000, @@ -1093,6 +1062,8 @@ static struct perflock_platform_data htcleo_perflock_data = { .perf_acpu_table = htcleo_perf_acpu_table, .table_size = ARRAY_SIZE(htcleo_perf_acpu_table), }; +#endif + /////////////////////////////////////////////////////////////////////// // Reset /////////////////////////////////////////////////////////////////////// @@ -1139,7 +1110,9 @@ static void __init htcleo_init(void) msm_acpu_clock_init(&htcleo_clock_data); +#ifdef CONFIG_PERFLOCK perflock_init(&htcleo_perflock_data); +#endif #if defined(CONFIG_MSM_SERIAL_DEBUGGER) msm_serial_debug_init(MSM_UART1_PHYS, INT_UART1, diff --git a/arch/arm/mach-msm/board-htcleo.h b/arch/arm/mach-msm/board-htcleo.h index d3777317..fcab3fe5 100644 --- a/arch/arm/mach-msm/board-htcleo.h +++ b/arch/arm/mach-msm/board-htcleo.h @@ -178,7 +178,8 @@ /* Voltage driver */ #define HTCLEO_TPS65023_MIN_UV_MV (800) -#define HTCLEO_TPS65023_MAX_UV_MV (1350) +#define HTCLEO_TPS65023_MAX_UV_MV (1375) +#define HTCLEO_TPS65023_UV_STEP_MV (25) /* LEDS */ #define LED_RGB (1 << 0) @@ -196,11 +197,12 @@ struct microp_led_platform_data { int num_leds; }; - - - int htcleo_pm_set_vreg(int enable, unsigned id); int __init htcleo_init_panel(void); int htcleo_is_nand_boot(void); +unsigned htcleo_get_vbus_state(void); +void config_camera_on_gpios(void); +void config_camera_off_gpios(void); +int is_valid_mac_address(char *mac); #endif /* __ARCH_ARM_MACH_MSM_BOARD_HTCLEO_H */ diff --git a/arch/arm/mach-msm/clock-wince.c b/arch/arm/mach-msm/clock-wince.c index a2b601b6..1903449b 100644 --- a/arch/arm/mach-msm/clock-wince.c +++ b/arch/arm/mach-msm/clock-wince.c @@ -34,6 +34,8 @@ //#define ENABLE_CLOCK_INFO 1 +extern struct clk msm_clocks[]; + static DEFINE_MUTEX(clocks_mutex); static DEFINE_SPINLOCK(clocks_lock); static LIST_HEAD(clocks); @@ -233,8 +235,16 @@ struct mdns_clock_params msm_clock_freq_parameters[] = { MSM_CLOCK_REG(64000000,0x19, 0x60, 0x30, 0, 2, 4, 1, 245760000), /* BT, 4000000 (*16) */ }; +int status_set_grp_clk = 0; +int i_set_grp_clk = 0; +int control_set_grp_clk; + static void set_grp_clk( int on ) { + int i = 0; + int status = 0; + int control; + if ( on != 0 ) { //axi_reset @@ -274,8 +284,7 @@ static void set_grp_clk( int on ) writel(readl(MSM_CLK_CTL_BASE) |0x8, MSM_CLK_CTL_BASE); //grp MD writel(readl(MSM_CLK_CTL_BASE+0x80) |0x1, MSM_CLK_CTL_BASE+0x80); //PRPH_WEB_NS_REG - int i = 0; - int status = 0; + while ( status == 0 && i < 100) { i++; status = readl(MSM_CLK_CTL_BASE+0x84) & 0x1; @@ -297,7 +306,7 @@ static void set_grp_clk( int on ) writel(readl(MSM_CLK_CTL_BASE+0x290) |0x4, MSM_CLK_CTL_BASE+0x290); //MSM_RAIL_CLAMP_IO writel( 0x11f, MSM_CLK_CTL_BASE+0x284); //VDD_GRP_GFS_CTL - int control = readl(MSM_CLK_CTL_BASE+0x288); //VDD_VDC_GFS_CTL + control = readl(MSM_CLK_CTL_BASE+0x288); //VDD_VDC_GFS_CTL if ( control & 0x100 ) writel(readl(MSM_CLK_CTL_BASE) &(~(0x8)), MSM_CLK_CTL_BASE); } @@ -1291,5 +1300,18 @@ static int __init clock_late_init(void) //pr_info("reset imem_config\n"); return 0; } - late_initcall(clock_late_init); + +struct clk_ops clk_ops_pcom = { + .enable = pc_clk_enable, + .disable = pc_clk_disable, + .auto_off = pc_clk_disable, +// .reset = pc_clk_reset, + .set_rate = pc_clk_set_rate, + .set_min_rate = pc_clk_set_min_rate, + .set_max_rate = pc_clk_set_max_rate, + .set_flags = pc_clk_set_flags, + .get_rate = pc_clk_get_rate, + .is_enabled = pc_clk_is_enabled, +// .round_rate = pc_clk_round_rate, +}; diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c index 81d2e296..5abc7d91 100644 --- a/arch/arm/mach-msm/clock.c +++ b/arch/arm/mach-msm/clock.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-msm/cpufreq.c b/arch/arm/mach-msm/cpufreq.c index 1fffb585..1c576c6d 100644 --- a/arch/arm/mach-msm/cpufreq.c +++ b/arch/arm/mach-msm/cpufreq.c @@ -17,6 +17,13 @@ * */ +#include +#include +#include +#include +#include +#include + #include #include #include diff --git a/arch/arm/mach-msm/dma.c b/arch/arm/mach-msm/dma.c index fd5133dc..69f0e09f 100644 --- a/arch/arm/mach-msm/dma.c +++ b/arch/arm/mach-msm/dma.c @@ -138,13 +138,14 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, complete(&cmd->complete); } -int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr) +int msm_dmov_exec_cmd(unsigned id, unsigned int crci_mask, unsigned int cmdptr) { struct msm_dmov_exec_cmdptr_cmd cmd; PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr); cmd.dmov_cmd.cmdptr = cmdptr; + cmd.dmov_cmd.crci_mask = crci_mask; cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func; cmd.dmov_cmd.execute_func = NULL; cmd.id = id; diff --git a/arch/arm/mach-msm/include/mach/board-htcleo-audio.h b/arch/arm/mach-msm/include/mach/board-htcleo-audio.h new file mode 100644 index 00000000..65b89af1 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/board-htcleo-audio.h @@ -0,0 +1,29 @@ +/* board-htcleo-mmc.h + * + * Copyright (C) 2011 marc1706 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef HTCLEO_AUDIO_H +#define HTCLEO_AUDIO_H + +void htcleo_headset_enable(int en); +void htcleo_speaker_enable(int en); +void htcleo_receiver_enable(int en); +void htcleo_bt_sco_enable(int en); +void htcleo_mic_enable(int en); +void htcleo_analog_init(void); +int htcleo_get_rx_vol(uint8_t hw, int level); +void __init htcleo_audio_init(void); + +#endif // HTCLEO_AUDIO_H + diff --git a/arch/arm/mach-msm/include/mach/board-htcleo-microp.h b/arch/arm/mach-msm/include/mach/board-htcleo-microp.h index dd77879e..39dc5516 100644 --- a/arch/arm/mach-msm/include/mach/board-htcleo-microp.h +++ b/arch/arm/mach-msm/include/mach/board-htcleo-microp.h @@ -136,4 +136,14 @@ struct microp_i2c_client_data { int microp_i2c_read(uint8_t addr, uint8_t *data, int length); int microp_i2c_write(uint8_t addr, uint8_t *data, int length); int capella_cm3602_power(int pwr_device, uint8_t enable); +int microp_read_gpo_status(uint16_t *status); +int microp_gpo_enable(uint16_t gpo_mask); +int microp_gpo_disable(uint16_t gpo_mask); + +#ifdef CONFIG_HAS_EARLYSUSPEND +void microp_early_suspend(struct early_suspend *h); +void microp_early_resume(struct early_suspend *h); +#endif // CONFIG_HAS_EARLYSUSPEND + + #endif diff --git a/arch/arm/mach-msm/include/mach/board-htcleo-mmc.h b/arch/arm/mach-msm/include/mach/board-htcleo-mmc.h new file mode 100644 index 00000000..8eaf392c --- /dev/null +++ b/arch/arm/mach-msm/include/mach/board-htcleo-mmc.h @@ -0,0 +1,31 @@ +/* board-htcleo-mmc.h + * + * Copyright (C) 2011 marc1706 + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef HTCLEO_MMC_H +#define HTCLEO_MMC_H + +static bool opt_disable_sdcard; +static void (*wifi_status_cb)(int card_present, void *dev_id); +static void *wifi_status_cb_devid; +static int htcleo_wifi_power_state; +static int htcleo_wifi_reset_state; + +int htcleo_wifi_set_carddetect(int val); +int htcleo_wifi_power(int on); +int htcleo_wifi_reset(int on); +int __init htcleo_init_mmc(unsigned debug_uart); + +#endif // HTCLEO_MMC_H + diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h index 91016443..cebfe9d0 100644 --- a/arch/arm/mach-msm/include/mach/board.h +++ b/arch/arm/mach-msm/include/mach/board.h @@ -178,6 +178,8 @@ enum { BOOTMODE_OFFMODE_CHARGING = 0x5, }; +void msm_hsusb_set_vbus_state(int online); + #define MSM_MAX_DEC_CNT 14 /* 7k target ADSP information */ /* Bit 23:0, for codec identification like mp3, wav etc * diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h index 7166756a..1dafddc2 100644 --- a/arch/arm/mach-msm/include/mach/camera.h +++ b/arch/arm/mach-msm/include/mach/camera.h @@ -32,6 +32,7 @@ #define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16 #define NUM_STAT_OUTPUT_BUFFERS 3 #define NUM_AF_STAT_OUTPUT_BUFFERS 3 +#define max_control_command_size 150 enum msm_queue { MSM_CAM_Q_CTRL, /* control command or control command status */ diff --git a/arch/arm/mach-msm/include/mach/clk.h b/arch/arm/mach-msm/include/mach/clk.h index 41a393b8..c45f6936 100644 --- a/arch/arm/mach-msm/include/mach/clk.h +++ b/arch/arm/mach-msm/include/mach/clk.h @@ -51,4 +51,7 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate); int clk_reset(struct clk *clk, enum clk_reset_action action); int clk_set_flags(struct clk *clk, unsigned long flags); + +unsigned long acpuclk_get_max_axi_rate(void); + #endif diff --git a/arch/arm/mach-msm/include/mach/debug_mm.h b/arch/arm/mach-msm/include/mach/debug_mm.h new file mode 100644 index 00000000..c46efa06 --- /dev/null +++ b/arch/arm/mach-msm/include/mach/debug_mm.h @@ -0,0 +1,47 @@ +/* Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of Code Aurora Forum, Inc. nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#ifndef __ARCH_ARM_MACH_MSM_DEBUG_MM_H_ +#define __ARCH_ARM_MACH_MSM_DEBUG_MM_H_ + +/* The below macro removes the directory path name and retains only the + * file name to avoid long path names in log messages that comes as + * part of __FILE__ to compiler. + */ +#define __MM_FILE__ strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/')+1) : \ + __FILE__ + +#define MM_DBG(fmt, args...) pr_debug("[%s] " fmt,\ + __func__, ##args) + +#define MM_INFO(fmt, args...) pr_info("[%s:%s] " fmt,\ + __MM_FILE__, __func__, ##args) + +#define MM_ERR(fmt, args...) pr_err("[%s:%s] " fmt,\ + __MM_FILE__, __func__, ##args) +#endif /* __ARCH_ARM_MACH_MSM_DEBUG_MM_H_ */ diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h index a6e7446d..6bd3de10 100644 --- a/arch/arm/mach-msm/include/mach/dma.h +++ b/arch/arm/mach-msm/include/mach/dma.h @@ -27,6 +27,7 @@ struct msm_dmov_errdata { struct msm_dmov_cmd { struct list_head list; unsigned int cmdptr; + unsigned int crci_mask; void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result, struct msm_dmov_errdata *err); @@ -38,7 +39,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd); void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd); void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful); void msm_dmov_flush(unsigned int id); -int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr); +int msm_dmov_exec_cmd(unsigned id, unsigned int crci_mask, unsigned int cmdptr); diff --git a/arch/arm/mach-msm/include/mach/irqs.h b/arch/arm/mach-msm/include/mach/irqs.h index e6bc7680..26d314af 100644 --- a/arch/arm/mach-msm/include/mach/irqs.h +++ b/arch/arm/mach-msm/include/mach/irqs.h @@ -311,6 +311,7 @@ #define INT_MDDI_CLIENT INT_MDC #define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE #define INT_NAND_OP_DONE INT_EBI2_OP_DONE +#define INT_GRAPHICS INT_GRP_3D #define NR_SIRC_IRQS 0 diff --git a/arch/arm/mach-msm/include/mach/msm_fb.h b/arch/arm/mach-msm/include/mach/msm_fb.h index e49eb454..8d20e545 100644 --- a/arch/arm/mach-msm/include/mach/msm_fb.h +++ b/arch/arm/mach-msm/include/mach/msm_fb.h @@ -27,10 +27,12 @@ struct mddi_info; #define MSM_MDP_OUT_IF_FMT_RGB888 2 /* mdp override operations */ -#define MSM_MDP_PANEL_IGNORE_PIXEL_DATA (1 << 0) +#define MSM_MDP_PANEL_IGNORE_PIXEL_DATA (1 << 0) #define MSM_MDP_PANEL_FLIP_UD (1 << 1) #define MSM_MDP_PANEL_FLIP_LR (1 << 2) #define MSM_MDP4_MDDI_DMA_SWITCH (1 << 3) +#define MSM_MDP_DMA_PACK_ALIGN_LSB (1 << 4) +#define MSM_MDP_RGB_PANEL_SELF_REFRESH (1 << 5) /* mddi type */ #define MSM_MDP_MDDI_TYPE_I 0 @@ -190,6 +192,7 @@ struct msm_lcdc_panel_ops { int (*uninit)(struct msm_lcdc_panel_ops *); int (*blank)(struct msm_lcdc_panel_ops *); int (*unblank)(struct msm_lcdc_panel_ops *); + int (*shutdown)(struct msm_lcdc_panel_ops *); }; struct msm_lcdc_platform_data { @@ -211,6 +214,8 @@ struct msm_tvenc_platform_data { struct mdp_blit_req; struct fb_info; +struct mdp_overlay; +struct msmfb_overlay_data; struct mdp_device { struct device dev; void (*dma)(struct mdp_device *mdp, uint32_t addr, @@ -227,14 +232,17 @@ struct mdp_device { int (*overlay_unset)(struct mdp_device *mdp, struct fb_info *fb, int ndx); int (*overlay_play)(struct mdp_device *mdp, struct fb_info *fb, - struct msmfb_overlay_data *req, struct file *p_src_file); + struct msmfb_overlay_data *req, struct file **p_src_file); #endif void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id); void (*configure_dma)(struct mdp_device *mdp); int (*check_output_format)(struct mdp_device *mdp, int bpp); int (*set_output_format)(struct mdp_device *mdp, int bpp); + void (*set_panel_size)(struct mdp_device *mdp, int width, int height); unsigned color_format; unsigned overrides; + uint32_t width; /*panel width*/ + uint32_t height; /*panel height*/ }; struct class_interface; diff --git a/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h b/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h index 1f6df9a4..fcbfbfcd 100644 --- a/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h +++ b/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h @@ -19,12 +19,14 @@ #define AUDIO_FLAG_READ 0 #define AUDIO_FLAG_WRITE 1 +#define AUDIO_FLAG_INCALL_MIXED 2 struct audio_buffer { dma_addr_t phys; void *data; uint32_t size; uint32_t used; /* 1 = CPU is waiting for DSP to consume this buf */ + uint32_t actual_size; /* actual number of bytes read by DSP */ }; struct audio_client { @@ -79,8 +81,10 @@ struct audio_client *q6audio_open_mp3(uint32_t bufsz, uint32_t rate, struct audio_client *q6fm_open(void); -struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate, - uint32_t flags, void *data, uint32_t acdb_id); +struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, + uint32_t channels, uint32_t bitrate, + uint32_t stream_format, uint32_t flags, + uint32_t acdb_id); struct audio_client *q6audio_open_qcelp(uint32_t bufsz, uint32_t rate, void *data, uint32_t acdb_id); @@ -102,7 +106,7 @@ int q6audio_set_tx_mute(int mute); int q6audio_reinit_acdb(char* filename); int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst); int q6audio_set_rx_volume(int level); -int q6audio_set_tx_volume(int level); +int q6audio_set_tx_volume(int mute); int q6audio_set_stream_volume(struct audio_client *ac, int vol); int q6audio_set_tx_dev_volume(int device_id, int level); int q6audio_get_tx_dev_volume(int device_id); diff --git a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h index 80c2b369..6d6c0de1 100644 --- a/arch/arm/mach-msm/include/mach/msm_rpcrouter.h +++ b/arch/arm/mach-msm/include/mach/msm_rpcrouter.h @@ -132,6 +132,8 @@ uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept); /* check if server version can handle client requested version */ int msm_rpc_is_compatible_version(uint32_t server_version, uint32_t client_version); +struct msm_rpc_endpoint *msm_rpc_connect_compatible(uint32_t prog, + uint32_t vers, unsigned flags); int msm_rpc_close(struct msm_rpc_endpoint *ept); int msm_rpc_write(struct msm_rpc_endpoint *ept, @@ -164,7 +166,7 @@ struct msm_rpc_xdr { void *in_buf; uint32_t in_size; uint32_t in_index; - struct mutex in_lock; + wait_queue_head_t in_buf_wait_q; void *out_buf; uint32_t out_size; @@ -174,6 +176,22 @@ struct msm_rpc_xdr { struct msm_rpc_endpoint *ept; }; +int xdr_send_int8(struct msm_rpc_xdr *xdr, const int8_t *value); +int xdr_send_uint8(struct msm_rpc_xdr *xdr, const uint8_t *value); +int xdr_send_int16(struct msm_rpc_xdr *xdr, const int16_t *value); +int xdr_send_uint16(struct msm_rpc_xdr *xdr, const uint16_t *value); +int xdr_send_int32(struct msm_rpc_xdr *xdr, const int32_t *value); +int xdr_send_uint32(struct msm_rpc_xdr *xdr, const uint32_t *value); +int xdr_send_bytes(struct msm_rpc_xdr *xdr, const void **data, uint32_t *size); + +int xdr_recv_int8(struct msm_rpc_xdr *xdr, int8_t *value); +int xdr_recv_uint8(struct msm_rpc_xdr *xdr, uint8_t *value); +int xdr_recv_int16(struct msm_rpc_xdr *xdr, int16_t *value); +int xdr_recv_uint16(struct msm_rpc_xdr *xdr, uint16_t *value); +int xdr_recv_int32(struct msm_rpc_xdr *xdr, int32_t *value); +int xdr_recv_uint32(struct msm_rpc_xdr *xdr, uint32_t *value); +int xdr_recv_bytes(struct msm_rpc_xdr *xdr, void **data, uint32_t *size); + struct msm_rpc_server { struct list_head list; diff --git a/arch/arm/mach-msm/include/mach/msm_smd.h b/arch/arm/mach-msm/include/mach/msm_smd.h index d9418bab..4dde12dc 100644 --- a/arch/arm/mach-msm/include/mach/msm_smd.h +++ b/arch/arm/mach-msm/include/mach/msm_smd.h @@ -63,6 +63,8 @@ int smd_wait_until_writable(smd_channel_t *ch, int bytes); #endif int smd_wait_until_opened(smd_channel_t *ch, int timeout_us); +int smd_total_fifo_size(smd_channel_t *ch); + typedef enum { SMD_PORT_DS = 0, diff --git a/arch/arm/mach-msm/pm.c b/arch/arm/mach-msm/pm.c index f3b17f22..ed19e679 100644 --- a/arch/arm/mach-msm/pm.c +++ b/arch/arm/mach-msm/pm.c @@ -142,13 +142,15 @@ int msm_irq_idle_sleep_allowed(void); int msm_irq_pending(void); int clks_allow_tcxo_locked_debug(void); extern int board_mfg_mode(void); -extern char * board_get_mfg_sleep_gpio_table(void); +extern unsigned long * board_get_mfg_sleep_gpio_table(void); extern void gpio_set_diag_gpio_table(unsigned long * dwMFG_gpio_table); extern void wait_rmt_final_call_back(int timeout); +#ifdef CONFIG_AXI_SCREEN_POLICY static int axi_rate; static int sleep_axi_rate; static struct clk *axi_clk; +#endif static uint32_t *msm_pm_reset_vector; static uint32_t msm_pm_max_sleep_time; @@ -654,8 +656,8 @@ static int msm_wakeup_after; /* default, no wakeup by alarm */ static int msm_power_wakeup_after(const char *val, struct kernel_param *kp) { int ret; - struct uart_port *port; - struct msm_port *msm_port; + //struct uart_port *port; + //struct msm_port *msm_port; ret = param_set_int(val, kp); printk(KERN_INFO "+msm_power_wakeup_after, ret=%d\r\n", ret); @@ -681,7 +683,7 @@ static void msm_pm_power_off(void) pmic_glb_power_down(); -#if CONFIG_MSM_RMT_STORAGE_SERVER +#ifdef CONFIG_MSM_RMT_STORAGE_SERVER printk(KERN_INFO "from %s\r\n", __func__); wait_rmt_final_call_back(10); printk(KERN_INFO "back %s\r\n", __func__); @@ -715,7 +717,7 @@ void msm_pm_flush_console(void) } #if defined(CONFIG_MACH_HTCLEO) -static void htcleo_save_reset_reason() +static void htcleo_save_reset_reason(void) { /* save restart_reason to be accesible in bootloader @ ramconsole - 0x1000*/ uint32_t *bootloader_reset_reason = ioremap(0x2FFB0000, PAGE_SIZE); @@ -728,7 +730,7 @@ static void htcleo_save_reset_reason() } #endif -static void msm_pm_restart(char str) +static void msm_pm_restart(char str, const char *cmd) { msm_pm_flush_console(); @@ -742,7 +744,7 @@ static void msm_pm_restart(char str) else msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0); -#if CONFIG_MSM_RMT_STORAGE_SERVER +#ifdef CONFIG_MSM_RMT_STORAGE_SERVER printk(KERN_INFO "from %s\r\n", __func__); wait_rmt_final_call_back(10); printk(KERN_INFO "back %s\r\n", __func__); @@ -858,6 +860,7 @@ void msm_pm_set_max_sleep_time(int64_t max_sleep_time_ns) EXPORT_SYMBOL(msm_pm_set_max_sleep_time); #ifdef CONFIG_EARLYSUSPEND +#ifdef CONFIG_AXI_SCREEN_POLICY /* axi 128 screen on, 61mhz screen off */ static void axi_early_suspend(struct early_suspend *handler) { @@ -877,7 +880,9 @@ static struct early_suspend axi_screen_suspend = { .resume = axi_late_resume, }; #endif +#endif +#ifdef CONFIG_AXI_SCREEN_POLICY static void __init msm_pm_axi_init(void) { #ifdef CONFIG_EARLYSUSPEND @@ -895,19 +900,18 @@ static void __init msm_pm_axi_init(void) axi_rate = 0; #endif } +#endif static int __init msm_pm_init(void) { pm_power_off = msm_pm_power_off; arm_pm_restart = msm_pm_restart; msm_pm_max_sleep_time = 0; -#if defined(CONFIG_ARCH_MSM_SCORPION) #ifdef CONFIG_AXI_SCREEN_POLICY msm_pm_axi_init(); #endif -#endif - register_reboot_notifier(&msm_reboot_notifier); + msm_pm_reset_vector = ioremap(0x0, PAGE_SIZE); #if defined(CONFIG_MACH_HTCLEO) diff --git a/arch/arm/mach-msm/pwrtest.c b/arch/arm/mach-msm/pwrtest.c index cc451be5..18c87196 100644 --- a/arch/arm/mach-msm/pwrtest.c +++ b/arch/arm/mach-msm/pwrtest.c @@ -14,6 +14,7 @@ * */ #include +#include #include "devices.h" #include "proc_comm.h" diff --git a/arch/arm/mach-msm/qdsp6_1550/aac_in.c b/arch/arm/mach-msm/qdsp6_1550/aac_in.c index 9b9f1c46..23455666 100644 --- a/arch/arm/mach-msm/qdsp6_1550/aac_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/aac_in.c @@ -1,7 +1,7 @@ -/* arch/arm/mach-msm/qdsp6/aac_in.c - * +/* * Copyright (C) 2009 Google, Inc. * Copyright (C) 2009 HTC Corporation + * Copyright (c) 2010, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -12,8 +12,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * -*/ + */ +#include #include #include #include @@ -21,197 +22,449 @@ #include #include #include -#include +#include +#include +#include + +#include +#include #include +#include -#define BUFSZ (4096) -#define DMASZ (BUFSZ * 2) +#define AAC_FC_BUFF_CNT 10 +#define AAC_READ_TIMEOUT 2000 +struct aac_fc_buff { + struct mutex lock; + int empty; + void *data; + int size; + int actual_size; +}; -#if 0 -#define TRACE(x...) pr_info("Q6: "x) -#else -#define TRACE(x...) do{}while(0) -#endif +struct aac_fc { + struct task_struct *task; + wait_queue_head_t fc_wq; + struct aac_fc_buff fc_buff[AAC_FC_BUFF_CNT]; + int buff_index; +}; +struct aac { + struct mutex lock; + struct msm_audio_aac_enc_config cfg; + struct msm_audio_stream_config str_cfg; + struct audio_client *audio_client; + struct msm_voicerec_mode voicerec_mode; + struct aac_fc *aac_fc; +}; -static DEFINE_MUTEX(aac_in_lock); -static int aac_in_opened = 0; -static struct aac_format *af; - -void audio_client_dump(struct audio_client *ac); - -static long aac_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - int rc = 0; - - switch (cmd) { - case AUDIO_SET_VOLUME: - break; - case AUDIO_GET_STATS: { - struct msm_audio_stats stats; - memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void*) arg, &stats, sizeof(stats))) - return -EFAULT; - return 0; - } - case AUDIO_START: { - uint32_t acdb_id; - rc = 0; - - if (arg == 0) { - acdb_id = 0; - } else if (copy_from_user(&acdb_id, - (void*) arg, sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - - mutex_lock(&aac_in_lock); - if (file->private_data) { - rc = -EBUSY; - } else { - file->private_data = q6audio_open_aac( - BUFSZ, 48000, AUDIO_FLAG_READ, af, acdb_id); - if (!file->private_data) - rc = -ENOMEM; - } - mutex_unlock(&aac_in_lock); - break; - } - case AUDIO_STOP: - break; - case AUDIO_FLUSH: - break; - case AUDIO_SET_CONFIG: { - struct msm_audio_config config; - if (copy_from_user(&config, (void*) arg, sizeof(config))) { - rc = -EFAULT; - break; - } - if (config.sample_rate != 48000) - pr_info("only 48KHz AAC encode supported\n"); - af->channel_config = config.channel_count; - break; - } - case AUDIO_GET_CONFIG: { - struct msm_audio_config config; - config.buffer_size = BUFSZ; - config.buffer_count = 2; - config.sample_rate = 48000; - config.channel_count = af->channel_config; - config.unused[0] = 0; - config.unused[1] = 0; - config.unused[2] = 0; - if (copy_to_user((void*) arg, &config, sizeof(config))) { - rc = -EFAULT; - } - break; - } - default: - rc = -EINVAL; - } - return rc; -} - -static int aac_in_open(struct inode *inode, struct file *file) -{ - int rc; - - pr_info("aac_in: open\n"); - mutex_lock(&aac_in_lock); - if (aac_in_opened) { - pr_err("aac_in: busy\n"); - rc = -EBUSY; - } else { - af = kzalloc(sizeof(*af), GFP_KERNEL); - memset(af, 0, sizeof(struct aac_format)); - af->sample_rate = 3; /* 48000 */ - af->channel_config = 1; - af->block_formats = AUDIO_AAC_FORMAT_ADTS; - af->audio_object_type = 2; /* CAD to ADSP format */ - af->bit_rate = 192000; - - aac_in_opened = 1; - rc = 0; - } - mutex_unlock(&aac_in_lock); - return rc; -} - -static ssize_t aac_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) +static int q6_aac_flowcontrol(void *data) { struct audio_client *ac; struct audio_buffer *ab; - const char __user *start = buf; - int xfer, res = 0; + struct aac *aac = data; + int buff_index = 0; + int xfer = 0; + struct aac_fc *fc; + + + ac = aac->audio_client; + fc = aac->aac_fc; + if (!ac) { + pr_err("[%s:%s] audio_client is NULL\n", __MM_FILE__, __func__); + return 0; + } + + while (!kthread_should_stop()) { + ab = ac->buf + ac->cpu_buf; + if (ab->used) + wait_event(ac->wait, (ab->used == 0)); + pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d\n", __MM_FILE__, + __func__, ab->data, ac->cpu_buf); + xfer = ab->actual_size; + + mutex_lock(&(fc->fc_buff[buff_index].lock)); + if (!fc->fc_buff[buff_index].empty) { + pr_err("[%s:%s] flow control buffer[%d] not read!\n", + __MM_FILE__, __func__, buff_index); + } + + if (fc->fc_buff[buff_index].size < xfer) { + pr_err("[%s:%s] buffer %d too small\n", __MM_FILE__, + __func__, buff_index); + memcpy(fc->fc_buff[buff_index].data, + ab->data, fc->fc_buff[buff_index].size); + fc->fc_buff[buff_index].empty = 0; + fc->fc_buff[buff_index].actual_size = + fc->fc_buff[buff_index].size; + } else { + memcpy(fc->fc_buff[buff_index].data, ab->data, xfer); + fc->fc_buff[buff_index].empty = 0; + fc->fc_buff[buff_index].actual_size = xfer; + } + mutex_unlock(&(fc->fc_buff[buff_index].lock)); + /*wake up client, if any*/ + wake_up(&fc->fc_wq); + + buff_index++; + if (buff_index >= AAC_FC_BUFF_CNT) + buff_index = 0; + + ab->used = 1; + + q6audio_read(ac, ab); + ac->cpu_buf ^= 1; + } + + return 0; +} +static long q6_aac_in_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct aac *aac = file->private_data; + int rc = 0; + int i = 0; + struct aac_fc *fc; + int size = 0; + + mutex_lock(&aac->lock); + switch (cmd) { + case AUDIO_SET_VOLUME: + break; + case AUDIO_GET_STATS: + { + struct msm_audio_stats stats; + pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); + memset(&stats, 0, sizeof(stats)); + if (copy_to_user((void *) arg, &stats, sizeof(stats))) + return -EFAULT; + return 0; + } + case AUDIO_START: + { + uint32_t acdb_id; + pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); + if (arg == 0) { + acdb_id = 0; + } else { + if (copy_from_user(&acdb_id, (void *) arg, + sizeof(acdb_id))) { + rc = -EFAULT; + break; + } + } + if (aac->audio_client) { + rc = -EBUSY; + pr_err("[%s:%s] active session already existing\n", + __MM_FILE__, __func__); + break; + } else { + aac->audio_client = q6audio_open_aac( + aac->str_cfg.buffer_size, + aac->cfg.sample_rate, + aac->cfg.channels, + aac->cfg.bit_rate, + aac->cfg.stream_format, + aac->voicerec_mode.rec_mode, acdb_id); + + if (aac->audio_client < 0) { + pr_err("[%s:%s] aac open session failed\n", + __MM_FILE__, __func__); + rc = -ENOMEM; + break; + } + } + + /*allocate flow control buffers*/ + fc = aac->aac_fc; + size = ((aac->str_cfg.buffer_size < 1543) ? 1543 : + aac->str_cfg.buffer_size); + for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { + mutex_init(&(fc->fc_buff[i].lock)); + fc->fc_buff[i].empty = 1; + fc->fc_buff[i].data = kmalloc(size, GFP_KERNEL); + if (fc->fc_buff[i].data == NULL) { + pr_err("[%s:%s] No memory for FC buffers\n", + __MM_FILE__, __func__); + rc = -ENOMEM; + goto fc_fail; + } + fc->fc_buff[i].size = size; + fc->fc_buff[i].actual_size = 0; + } + + /*create flow control thread*/ + fc->task = kthread_run(q6_aac_flowcontrol, + aac, "aac_flowcontrol"); + if (IS_ERR(fc->task)) { + rc = PTR_ERR(fc->task); + pr_err("[%s:%s] error creating flow control thread\n", + __MM_FILE__, __func__); + goto fc_fail; + } + break; +fc_fail: + /*free flow control buffers*/ + --i; + for (; i >= 0; i--) { + kfree(fc->fc_buff[i].data); + fc->fc_buff[i].data = NULL; + } + break; + } + case AUDIO_STOP: + pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); + break; + case AUDIO_FLUSH: + break; + case AUDIO_SET_INCALL: { + pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); + if (copy_from_user(&aac->voicerec_mode, + (void *)arg, sizeof(struct msm_voicerec_mode))) + rc = -EFAULT; + + if (aac->voicerec_mode.rec_mode != AUDIO_FLAG_READ + && aac->voicerec_mode.rec_mode != + AUDIO_FLAG_INCALL_MIXED) { + aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; + pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, + __func__); + rc = -EINVAL; + } + break; + } + case AUDIO_GET_STREAM_CONFIG: + if (copy_to_user((void *)arg, &aac->str_cfg, + sizeof(struct msm_audio_stream_config))) + rc = -EFAULT; + pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", + __MM_FILE__, __func__, aac->str_cfg.buffer_size, + aac->str_cfg.buffer_count); + break; + case AUDIO_SET_STREAM_CONFIG: + if (copy_from_user(&aac->str_cfg, (void *)arg, + sizeof(struct msm_audio_stream_config))) { + rc = -EFAULT; + break; + } + pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", + __MM_FILE__, __func__, aac->str_cfg.buffer_size, + aac->str_cfg.buffer_count); + if (aac->str_cfg.buffer_size < 1543) { + pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, + __func__); + rc = -EINVAL; + break; + } + if (aac->str_cfg.buffer_count != 2) + pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, + __func__); + + break; + case AUDIO_SET_AAC_ENC_CONFIG: + if (copy_from_user(&aac->cfg, (void *) arg, + sizeof(struct msm_audio_aac_enc_config))) { + rc = -EFAULT; + } + pr_debug("[%s:%s] SET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", + __MM_FILE__, __func__, aac->cfg.channels, + aac->cfg.sample_rate); + if (aac->cfg.channels < 1 || aac->cfg.channels > 2) { + pr_err("[%s:%s]invalid number of channels\n", + __MM_FILE__, __func__); + rc = -EINVAL; + } + if (aac->cfg.sample_rate != 48000) { + pr_err("[%s:%s] only 48KHz is supported\n", + __MM_FILE__, __func__); + rc = -EINVAL; + } + if (aac->cfg.stream_format != AUDIO_AAC_FORMAT_RAW && + aac->cfg.stream_format != AUDIO_AAC_FORMAT_ADTS) { + pr_err("[%s:%s] unsupported AAC format\n", __MM_FILE__, + __func__); + rc = -EINVAL; + } + break; + case AUDIO_GET_AAC_ENC_CONFIG: + if (copy_to_user((void *) arg, &aac->cfg, + sizeof(struct msm_audio_aac_enc_config))) { + rc = -EFAULT; + } + pr_debug("[%s:%s] GET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", + __MM_FILE__, __func__, aac->cfg.channels, + aac->cfg.sample_rate); + break; + default: + rc = -EINVAL; + } + + mutex_unlock(&aac->lock); + pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); + return rc; +} + +static int q6_aac_in_open(struct inode *inode, struct file *file) +{ + + struct aac *aac; + struct aac_fc *fc; + int i; + pr_info("[%s:%s] open\n", __MM_FILE__, __func__); + aac = kmalloc(sizeof(struct aac), GFP_KERNEL); + if (aac == NULL) { + pr_err("[%s:%s] Could not allocate memory for aac driver\n", + __MM_FILE__, __func__); + return -ENOMEM; + } + + mutex_init(&aac->lock); + file->private_data = aac; + aac->audio_client = NULL; + aac->str_cfg.buffer_size = 1543; + aac->str_cfg.buffer_count = 2; + aac->cfg.channels = 1; + aac->cfg.bit_rate = 192000; + aac->cfg.stream_format = AUDIO_AAC_FORMAT_ADTS; + aac->cfg.sample_rate = 48000; + aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; + + aac->aac_fc = kmalloc(sizeof(struct aac_fc), GFP_KERNEL); + if (aac->aac_fc == NULL) { + pr_err("[%s:%s] Could not allocate memory for aac_fc\n", + __MM_FILE__, __func__); + kfree(aac); + return -ENOMEM; + } + fc = aac->aac_fc; + fc->task = NULL; + fc->buff_index = 0; + for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { + fc->fc_buff[i].data = NULL; + fc->fc_buff[i].size = 0; + fc->fc_buff[i].actual_size = 0; + } + /*initialize wait queue head*/ + init_waitqueue_head(&fc->fc_wq); + return 0; +} + +static ssize_t q6_aac_in_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + struct audio_client *ac; + const char __user *start = buf; + struct aac *aac = file->private_data; + struct aac_fc *fc; + int xfer = 0; + int res = 0; + + pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); + mutex_lock(&aac->lock); + ac = aac->audio_client; - mutex_lock(&aac_in_lock); - ac = file->private_data; if (!ac) { res = -ENODEV; goto fail; } - while (count > 0) { - ab = ac->buf + ac->cpu_buf; + fc = aac->aac_fc; - if (ab->used) - if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { - audio_client_dump(ac); - pr_err("aac_read: timeout. dsp dead?\n"); - BUG(); - } + /*wait for buffer to full*/ + if (fc->fc_buff[fc->buff_index].empty != 0) { + res = wait_event_interruptible_timeout(fc->fc_wq, + (fc->fc_buff[fc->buff_index].empty == 0), + msecs_to_jiffies(AAC_READ_TIMEOUT)); - xfer = count; - if (xfer > ab->size) - xfer = ab->size; - - if (copy_to_user(buf, ab->data, xfer)) { - res = -EFAULT; + pr_debug("[%s:%s] buff_index = %d\n", __MM_FILE__, + __func__, fc->buff_index); + if (res == 0) { + pr_err("[%s:%s] Timeout!\n", __MM_FILE__, __func__); + res = -ETIMEDOUT; + goto fail; + } else if (res < 0) { + pr_err("[%s:%s] Returning on Interrupt\n", __MM_FILE__, + __func__); goto fail; } - - buf += xfer; - count -= xfer; - - ab->used = 1; - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; } -fail: + /*lock the buffer*/ + mutex_lock(&(fc->fc_buff[fc->buff_index].lock)); + xfer = fc->fc_buff[fc->buff_index].actual_size; + + if (xfer > count) { + mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); + pr_err("[%s:%s] read failed! byte count too small\n", + __MM_FILE__, __func__); + res = -EINVAL; + goto fail; + } + + if (copy_to_user(buf, fc->fc_buff[fc->buff_index].data, xfer)) { + mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); + pr_err("[%s:%s] copy_to_user failed at index %d\n", + __MM_FILE__, __func__, fc->buff_index); + res = -EFAULT; + goto fail; + } + + buf += xfer; + + fc->fc_buff[fc->buff_index].empty = 1; + fc->fc_buff[fc->buff_index].actual_size = 0; + + mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); + ++(fc->buff_index); + if (fc->buff_index >= AAC_FC_BUFF_CNT) + fc->buff_index = 0; + res = buf - start; - mutex_unlock(&aac_in_lock); +fail: + mutex_unlock(&aac->lock); + return res; } -static int aac_in_release(struct inode *inode, struct file *file) +static int q6_aac_in_release(struct inode *inode, struct file *file) { int rc = 0; - pr_info("aac_in: release\n"); - mutex_lock(&aac_in_lock); - if (file->private_data) - rc = q6audio_close(file->private_data); - kfree(af); - aac_in_opened = 0; - mutex_unlock(&aac_in_lock); + struct aac *aac = file->private_data; + int i = 0; + struct aac_fc *fc; + + mutex_lock(&aac->lock); + fc = aac->aac_fc; + kthread_stop(fc->task); + fc->task = NULL; + + /*free flow control buffers*/ + for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { + kfree(fc->fc_buff[i].data); + fc->fc_buff[i].data = NULL; + } + kfree(fc); + if (aac->audio_client) + rc = q6audio_close(aac->audio_client); + mutex_unlock(&aac->lock); + kfree(aac); + pr_info("[%s:%s] release\n", __MM_FILE__, __func__); return rc; } -static struct file_operations aac_in_fops = { - .owner = THIS_MODULE, - .open = aac_in_open, - .read = aac_in_read, - .release = aac_in_release, - .unlocked_ioctl = aac_in_ioctl, +static const struct file_operations q6_aac_in_fops = { + .owner = THIS_MODULE, + .open = q6_aac_in_open, + .read = q6_aac_in_read, + .release = q6_aac_in_release, + .unlocked_ioctl = q6_aac_in_ioctl, }; -struct miscdevice aac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &aac_in_fops, +struct miscdevice q6_aac_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_aac_in", + .fops = &q6_aac_in_fops, }; -static int __init aac_in_init(void) { - return misc_register(&aac_in_misc); +static int __init q6_aac_in_init(void) +{ + return misc_register(&q6_aac_in_misc); } -device_initcall(aac_in_init); +device_initcall(q6_aac_in_init); diff --git a/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c b/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c index eaf5a942..e37296a4 100644 --- a/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c +++ b/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -133,8 +133,7 @@ static int q6_open(struct inode *inode, struct file *file) return 0; } -static int q6_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +static long q6_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int rc; uint32_t n; @@ -147,28 +146,40 @@ static int q6_ioctl(struct inode *inode, struct file *file, case AUDIO_SWITCH_DEVICE: rc = copy_from_user(&id, (void *)arg, sizeof(id)); AUDIO_INFO("SWITCH DEVICE %d, acdb %d\n", id[0], id[1]); - if (!rc) + if (rc) { + pr_err("%s: bad user address\n", __func__); + rc = -EFAULT; + } else rc = q6audio_do_routing(id[0], id[1]); break; case AUDIO_SET_VOLUME: rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) + if (rc) { + pr_err("%s: bad user address\n", __func__); + rc = -EFAULT; + } else rc = q6audio_set_rx_volume(n); break; case AUDIO_SET_MUTE: rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (!rc) + if (rc) { + pr_err("%s: bad user address\n", __func__); + rc = -EFAULT; + } else rc = q6audio_set_tx_mute(n); break; case AUDIO_UPDATE_ACDB: rc = copy_from_user(&id, (void *)arg, sizeof(id)); - if (!rc) + if (rc) { + pr_err("%s: bad user address\n", __func__); + rc = -EFAULT; + } else rc = q6audio_update_acdb(id[0], id[1]); break; case AUDIO_START_VOICE: - if (arg == 0) { + if (arg == 0) id[0] = id[1] = 0; - } else if (copy_from_user(&id, (void*) arg, sizeof(id))) { + else if (copy_from_user(&id, (void*) arg, sizeof(id))) { pr_info("voice: copy acdb_id from user failed\n"); rc = -EFAULT; break; diff --git a/arch/arm/mach-msm/qdsp6_1550/dal.c b/arch/arm/mach-msm/qdsp6_1550/dal.c index d05ccfb0..f0374dfc 100644 --- a/arch/arm/mach-msm/qdsp6_1550/dal.c +++ b/arch/arm/mach-msm/qdsp6_1550/dal.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/mp3.c b/arch/arm/mach-msm/qdsp6_1550/mp3.c index c04fc5d1..6b402c27 100644 --- a/arch/arm/mach-msm/qdsp6_1550/mp3.c +++ b/arch/arm/mach-msm/qdsp6_1550/mp3.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c index 69ce1804..2f525c8c 100644 --- a/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c +++ b/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c b/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c index f32f2825..269b0a41 100644 --- a/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c +++ b/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -358,7 +359,7 @@ static int q6_encode(struct q6venc_dev *q6venc, struct encode_param *enc_param) { struct q6_encode_param *q6_param = &enc_param->q6_encode_param; struct file *file; - struct buf_info *buf; + struct buf_info *buf = 0; int i; int ret; int rlc_buf_index; diff --git a/arch/arm/mach-msm/qdsp6_1550/pcm_in.c b/arch/arm/mach-msm/qdsp6_1550/pcm_in.c index ad84f53f..36abf17b 100644 --- a/arch/arm/mach-msm/qdsp6_1550/pcm_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/pcm_in.c @@ -14,6 +14,7 @@ * */ +#include #include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/pcm_out.c b/arch/arm/mach-msm/qdsp6_1550/pcm_out.c index b3fbc8e6..eb8dae95 100644 --- a/arch/arm/mach-msm/qdsp6_1550/pcm_out.c +++ b/arch/arm/mach-msm/qdsp6_1550/pcm_out.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -64,6 +65,12 @@ static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_SET_VOLUME: { int vol; + if (!pcm->ac) { + pr_err("%s: cannot set volume before AUDIO_START!\n", + __func__); + rc = -EINVAL; + break; + } if (copy_from_user(&vol, (void*) arg, sizeof(vol))) { rc = -EFAULT; break; diff --git a/arch/arm/mach-msm/qdsp6_1550/q6audio.c b/arch/arm/mach-msm/qdsp6_1550/q6audio.c index 8113ca19..0c8b2d30 100644 --- a/arch/arm/mach-msm/qdsp6_1550/q6audio.c +++ b/arch/arm/mach-msm/qdsp6_1550/q6audio.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -32,11 +33,12 @@ #include "dal_acdb.h" #include "dal_adie.h" #include -#include +#include #include #include #include +#include #include "q6audio_devices.h" #include "../dex_comm.h" @@ -172,7 +174,7 @@ static struct audio_client * audio_test(void); static void callback(void *data, int len, void *cookie); static int audio_init(struct audio_client *ac); static int audio_info(struct audio_client *ac); -static int q6audio_init_rx_volumes(); +static int q6audio_init_rx_volumes(void); static struct wake_lock wakelock; static struct wake_lock idlelock; @@ -215,6 +217,7 @@ static char acdb_file[64] = "default.acdb"; static uint32_t tx_acdb = 0; static uint32_t rx_acdb = 0; static int acdb_use_rpc = 0; +static int acdb_use_map = 0; ///////////////////////////////////////////////////////////////////////////////// // helper functions for device parameters @@ -699,10 +702,18 @@ static int audio_mp3_open(struct audio_client *ac, uint32_t bufsz, return ac->open_status; } -static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data) +/* + * ported code for audio_aac_open from Code Aurora in order to work + * with new aac code from Code Aurora + * by marc1706 + */ +static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, + uint32_t sample_rate, uint32_t channels, + uint32_t bit_rate, uint32_t flags, + uint32_t stream_format) { int r; - struct aac_format *af = data; + int audio_object_type; struct adsp_open_command rpc; uint32_t *aac_type; int idx = 0; // sizeof(uint32_t); @@ -723,77 +734,33 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data) rpc.pblock = params_phys; aac_type = (uint32_t *)(fmt->data); - switch (af->block_formats) + switch (stream_format) { - case 0xffff: - if (ac->flags & AUDIO_FLAG_WRITE) - *aac_type = ADSP_AUDIO_AAC_ADTS; - else - *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; - break; - case 0: - if (ac->flags & AUDIO_FLAG_WRITE) - *aac_type = ADSP_AUDIO_AAC_ADIF; - else - *aac_type = ADSP_AUDIO_AAC_RAW; - break; - case 1: - *aac_type = ADSP_AUDIO_AAC_RAW; - break; - case 2: - *aac_type = ADSP_AUDIO_AAC_LOAS; - break; - case 3: - *aac_type = ADSP_AUDIO_AAC_FRAMED_RAW; - break; - case 4: - *aac_type = ADSP_AUDIO_AAC_RAW; - break; + case AUDIO_AAC_FORMAT_ADTS: + /* AAC Encoder expect MPEG4_ADTS media type */ + *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; + break; + case AUDIO_AAC_FORMAT_RAW: + /* for ADIF recording */ + *aac_type = ADSP_AUDIO_AAC_RAW; + break; default: - pr_err("unsupported AAC type %d\n", af->block_formats); + pr_err("unsupported AAC type %d\n", stream_format); mutex_unlock(&open_mem_lock); return -EINVAL; } + + /* AAC OBJECT LC */ + audio_object_type = 2; AUDIO_INFO("aac_open: type %x, obj %d, idx %d\n", - *aac_type, af->audio_object_type, idx); - fmt->data[idx++] = (u8)(((af->audio_object_type & 0x1F) << 3) | - ((af->sample_rate >> 1) & 0x7)); - fmt->data[idx] = (u8)(((af->sample_rate & 0x1) << 7) | - ((af->channel_config & 0x7) << 3)); + *aac_type, audio_object_type, idx); - switch (af->audio_object_type) { - case AAC_OBJECT_ER_LC: - case AAC_OBJECT_ER_LTP: - case AAC_OBJECT_ER_LD: - /* extension flag */ - fmt->data[idx++] |= 0x1; - fmt->data[idx] = (u8)( - ((af->aac_section_data_resilience_flag & 0x1) << 7) | - ((af->aac_scalefactor_data_resilience_flag & 0x1) << 6) | - ((af->aac_spectral_data_resilience_flag & 0x1) << 5) | - ((af->ep_config & 0x3) << 2)); - break; + fmt->data[idx++] = (u8)(((audio_object_type & 0x1F) << 3) | + ((sample_rate >> 1) & 0x7)); + fmt->data[idx] = (u8)(((sample_rate & 0x1) << 7) | + ((channels & 0x7) << 3)); - case AAC_OBJECT_ER_SCALABLE: - fmt->data[idx++] |= 0x1; - /* extension flag */ - fmt->data[idx++] = (u8)( - ((af->aac_section_data_resilience_flag & 0x1) << 4) | - ((af->aac_scalefactor_data_resilience_flag & 0x1) << 3) | - ((af->aac_spectral_data_resilience_flag & 0x1) << 2) | - ((af->ep_config >> 1) & 0x1)); - fmt->data[idx] = (u8)((af->ep_config & 0x1) << 7); - break; - - case AAC_OBJECT_BSAC: - fmt->data[++idx] = (u8)((af->ep_config & 0x3) << 6); - break; - - default: - pr_err("dbg unknown object type \n"); - break; - } // fmt->num_bytes = idx + 1; rpc.blocklen = idx + 1; @@ -801,8 +768,8 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data) fmt->data[0], fmt->data[1], fmt->data[2], fmt->data[3], fmt->data[4], fmt->data[5], fmt->data[6], fmt->data[7]); - rpc.config.aac.bit_rate = af->bit_rate; - if (ac->flags & AUDIO_FLAG_WRITE) + rpc.config.aac.bit_rate = bit_rate; + if (flags & AUDIO_FLAG_WRITE) { rpc.opcode = ADSP_AUDIO_OPCODE_OPEN_WRITE; rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; @@ -813,25 +780,13 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data) rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; } - if ((af->sbr_on_flag == 0) && (af->sbr_ps_on_flag == 0)) - { - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; - } - else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 0)) - { - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_PLUS_MODE; - } - else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 1)) - { - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE; - } - else - { - pr_err("unsupported SBR flag\n"); - mutex_unlock(&open_mem_lock); - return -EINVAL; - } - rpc.buf_max_size = bufsz; /* XXX ??? */ + /* + * Always use ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE as encoder_mode + * from Code Aurora + * by marc1706 + */ + rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; + rpc.buf_max_size = bufsz; TRACE("aac_open: opcode %x, stream_context 0x%x, " "mode %d, bytes %d, bbuffer size %d\n", @@ -1233,11 +1188,29 @@ static int acdb_init(char *filename) const struct firmware *fw; int n; + // return -ENODEV; + AUDIO_INFO("%s\n", __func__); +#ifdef CONFIG_MACH_HTCLEO + pr_info("acdb: trying htcleo.acdb\n"); + if(request_firmware(&fw, "htcleo.acdb", q6_control_device.this_device) < 0) { + pr_info("acdb: load 'htcleo.acdb' failed, trying 'default.acdb'\n"); + acdb_use_map = 0; + if (request_firmware(&fw, filename, q6_control_device.this_device) < 0) { + pr_err("acdb: load 'default.acdb' failed...\n"); + return -ENODEV; + } + } else { + pr_info("acdb: 'htcleo.acdb' found, using translation\n"); + acdb_use_map = 1; + } +#else pr_info("acdb: load '%s'\n", filename); + acd_use_map = 0; if (request_firmware(&fw, filename, q6_control_device.this_device) < 0) { pr_err("acdb: load 'default.acdb' failed...\n"); return -ENODEV; } +#endif db = (void*) fw->data; if (fw->size < sizeof(struct audio_config_database)) { @@ -1448,6 +1421,9 @@ static int acdb_get_config_table(uint32_t device_id, uint32_t sample_rate) int n; printk("table\n"); + // htcleo use custom table with wince values, it must be mapped + if(acdb_use_map) + device_id = map_cad_dev_to_virtual(device_id); db = acdb_data; for (n = 0; n < db->entry_count; n++) { @@ -2209,7 +2185,7 @@ int q6audio_set_rx_volume(int level) } EXPORT_SYMBOL_GPL(q6audio_set_rx_volume); -static int q6audio_init_rx_volumes() +static int q6audio_init_rx_volumes(void) { int vol; struct q6_device_info *di = q6_audio_devices; @@ -2628,14 +2604,19 @@ int q6audio_async(struct audio_client *ac) } - -struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate, - uint32_t flags, void *data, uint32_t acdb_id) +/* + * ported code for q6audio_open_aac from Code Aurora + * by marc1706 + */ +struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, + uint32_t channels, uint32_t bitrate, + uint32_t stream_format, uint32_t flags, + uint32_t acdb_id) { struct audio_client *ac; AUDIO_INFO("%s\n", __func__); - TRACE("q6audio_open_aac flags=%d rate=%d\n", flags, rate); + TRACE("q6audio_open_aac flags=%d samplerate=%d, channels = %d\n", flags, samplerate, channels); if (q6audio_init()) return 0; @@ -2648,12 +2629,13 @@ struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate, if (ac->flags & AUDIO_FLAG_WRITE) audio_rx_path_enable(1, acdb_id); else { - /* TODO: consider concourrency with voice call */ - tx_clk_freq = rate; + if (!audio_tx_path_refcount) + tx_clk_freq = 48000; audio_tx_path_enable(1, acdb_id); } - audio_aac_open(ac, bufsz, data); + audio_aac_open(ac, bufsz, samplerate, channels, bitrate, flags, + stream_format); audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); if (!(ac->flags & AUDIO_FLAG_WRITE)) { diff --git a/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c b/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c index 50c74259..80bb903d 100644 --- a/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c index 1b4ff1cb..50ee773f 100644 --- a/arch/arm/mach-msm/sirc.c +++ b/arch/arm/mach-msm/sirc.c @@ -188,6 +188,12 @@ static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc) (sirc_reg_table[reg].cascade_irq != irq)) reg++; + if (reg == ARRAY_SIZE(sirc_reg_table)) { + printk(KERN_ERR "%s: incorrect irq %d called\n", + __func__, irq); + return; + } + status = readl(sirc_reg_table[reg].int_status); status &= SIRC_MASK; if (status == 0) diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c index b8423029..23d67e8d 100644 --- a/arch/arm/mach-msm/smd.c +++ b/arch/arm/mach-msm/smd.c @@ -381,17 +381,18 @@ static void update_packet_state(struct smd_channel *ch) int r; /* can't do anything if we're in the middle of a packet */ - if (ch->current_packet != 0) - return; + while (ch->current_packet == 0) { + /* discard 0 length packets if any */ - /* don't bother unless we can get the full header */ - if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) - return; + /* don't bother unless we can get the full header */ + if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE) + return; - r = ch_read(ch, hdr, SMD_HEADER_SIZE); - BUG_ON(r != SMD_HEADER_SIZE); + r = ch_read(ch, hdr, SMD_HEADER_SIZE); + BUG_ON(r != SMD_HEADER_SIZE); - ch->current_packet = hdr[0]; + ch->current_packet = hdr[0]; + } } /* provide a pointer and length to next free space in the fifo */ @@ -490,7 +491,7 @@ static void handle_smd_irq(struct list_head *list, void (*notify)(void)) #ifdef CONFIG_BUILD_CIQ /* put here to make sure we got the disable/enable index */ if (!msm_smd_ciq_info) - msm_smd_ciq_info = (*(volatile uint32_t *)(MSM_SHARED_RAM_BASE + 0xFC11C)); + msm_smd_ciq_info = (*(volatile uint32_t *)(MSM_SHARED_RAM_BASE + SMD_CIQ_BASE)); #endif spin_lock_irqsave(&smd_lock, flags); list_for_each_entry(ch, list, ch_list) { @@ -641,6 +642,8 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len) if (len < 0) return -EINVAL; + else if (len == 0) + return 0; while ((xfer = ch_write_buffer(ch, &ptr)) != 0) { if (!ch_is_open(ch)) @@ -911,6 +914,7 @@ int smd_close(smd_channel_t *ch) return 0; } +EXPORT_SYMBOL(smd_close); int smd_read(smd_channel_t *ch, void *data, int len) { @@ -922,6 +926,7 @@ int smd_write(smd_channel_t *ch, const void *data, int len) { return ch->write(ch, data, len); } +EXPORT_SYMBOL(smd_write); int smd_write_atomic(smd_channel_t *ch, const void *data, int len) { @@ -944,6 +949,7 @@ int smd_write_avail(smd_channel_t *ch) { return ch->write_avail(ch); } +EXPORT_SYMBOL_GPL(smd_write_avail); int smd_wait_until_readable(smd_channel_t *ch, int bytes) { @@ -981,6 +987,11 @@ int smd_cur_packet_size(smd_channel_t *ch) } EXPORT_SYMBOL(smd_cur_packet_size); +/* Returns SMD buffer size */ +int smd_total_fifo_size(smd_channel_t *ch) +{ + return ch->fifo_size; +} /* ------------------------------------------------------------------------- */ diff --git a/arch/arm/mach-msm/smd_private.h b/arch/arm/mach-msm/smd_private.h index 71088e90..3dc0a203 100644 --- a/arch/arm/mach-msm/smd_private.h +++ b/arch/arm/mach-msm/smd_private.h @@ -89,6 +89,33 @@ struct smsm_interrupt_info { }; #endif +#if defined(CONFIG_MSM_N_WAY_SMSM) +enum { + SMSM_APPS_STATE, + SMSM_MODEM_STATE, + SMSM_Q6_STATE, + SMSM_APPS_DEM, + SMSM_MODEM_DEM, + SMSM_Q6_DEM, + SMSM_POWER_MASTER_DEM, + SMSM_TIME_MASTER_DEM, + SMSM_NUM_ENTRIES, +}; +#else +enum { + SMSM_APPS_STATE = 1, + SMSM_MODEM_STATE = 3, + SMSM_NUM_ENTRIES, +}; +#endif + +enum { + SMSM_APPS, + SMSM_MODEM, + SMSM_Q6, + SMSM_NUM_HOSTS, +}; + #define SZ_DIAG_ERR_MSG 0xC8 #define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE #define ID_SMD_CHANNELS SMEM_SMD_BASE_ID diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c index 413139af..4c0476eb 100644 --- a/arch/arm/mach-msm/smd_rpcrouter.c +++ b/arch/arm/mach-msm/smd_rpcrouter.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -105,7 +106,7 @@ static struct wake_lock rpcrouter_wake_lock; static int rpcrouter_need_len; static atomic_t next_xid = ATOMIC_INIT(1); -static uint8_t next_pacmarkid; +static atomic_t next_mid = ATOMIC_INIT(0); static void do_read_data(struct work_struct *work); static void do_create_pdevs(struct work_struct *work); @@ -114,12 +115,16 @@ static void do_create_rpcrouter_pdev(struct work_struct *work); static DECLARE_WORK(work_read_data, do_read_data); static DECLARE_WORK(work_create_pdevs, do_create_pdevs); static DECLARE_WORK(work_create_rpcrouter_pdev, do_create_rpcrouter_pdev); +static atomic_t rpcrouter_pdev_created = ATOMIC_INIT(0); #define RR_STATE_IDLE 0 #define RR_STATE_HEADER 1 #define RR_STATE_BODY 2 #define RR_STATE_ERROR 3 +#define RMT_STORAGE_APIPROG_BE32 0xa7000030 +#define RMT_STORAGE_SRV_APIPROG_BE32 0x9c000030 + struct rr_context { struct rr_packet *pkt; uint8_t *ptr; @@ -262,6 +267,7 @@ struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev) { struct msm_rpc_endpoint *ept; unsigned long flags; + int i; ept = kmalloc(sizeof(struct msm_rpc_endpoint), GFP_KERNEL); if (!ept) @@ -269,7 +275,9 @@ struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev) memset(ept, 0, sizeof(struct msm_rpc_endpoint)); /* mark no reply outstanding */ - ept->reply_pid = 0xffffffff; + ept->next_rroute = 0; + for (i = 0; i < MAX_REPLY_ROUTE; i++) + ept->rroute[i].pid = 0xffffffff; ept->cid = (uint32_t) ept; ept->pid = RPCROUTER_PID_LOCAL; @@ -530,7 +538,8 @@ static int process_control_msg(union rr_control_msg *msg, int len) static void do_create_rpcrouter_pdev(struct work_struct *work) { - platform_device_register(&rpcrouter_pdev); + if (atomic_cmpxchg(&rpcrouter_pdev_created, 0, 1) == 0) + platform_device_register(&rpcrouter_pdev); } static void do_create_pdevs(struct work_struct *work) @@ -652,11 +661,13 @@ static void do_read_data(struct work_struct *work) hdr.size -= sizeof(pm); - frag = rr_malloc(hdr.size + sizeof(*frag)); + frag = rr_malloc(sizeof(*frag)); frag->next = NULL; frag->length = hdr.size; - if (rr_read(frag->data, hdr.size)) + if (rr_read(frag->data, hdr.size)) { + kfree(frag); goto fail_io; + } ept = rpcrouter_lookup_local_endpoint(hdr.dst_cid); if (!ept) { @@ -758,19 +769,77 @@ int msm_rpc_close(struct msm_rpc_endpoint *ept) } EXPORT_SYMBOL(msm_rpc_close); +static int msm_rpc_write_pkt(struct msm_rpc_endpoint *ept, + struct rr_remote_endpoint *r_ept, + struct rr_header *hdr, + uint32_t pacmark, + void *buffer, int count) +{ + DEFINE_WAIT(__wait); + unsigned long flags; + int needed; + + for (;;) { + prepare_to_wait(&r_ept->quota_wait, &__wait, + TASK_INTERRUPTIBLE); + spin_lock_irqsave(&r_ept->quota_lock, flags); + if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA) + break; + if (signal_pending(current) && + (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) + break; + spin_unlock_irqrestore(&r_ept->quota_lock, flags); + schedule(); + } + finish_wait(&r_ept->quota_wait, &__wait); + + if (signal_pending(current) && + (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) { + spin_unlock_irqrestore(&r_ept->quota_lock, flags); + return -ERESTARTSYS; + } + r_ept->tx_quota_cntr++; + if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA) + hdr->confirm_rx = 1; + + spin_unlock_irqrestore(&r_ept->quota_lock, flags); + + spin_lock_irqsave(&smd_lock, flags); + + needed = sizeof(*hdr) + hdr->size; + while (smd_write_avail(smd_channel) < needed) { + spin_unlock_irqrestore(&smd_lock, flags); + msleep(250); + spin_lock_irqsave(&smd_lock, flags); + } + + /* TODO: deal with full fifo */ + smd_write(smd_channel, hdr, sizeof(*hdr)); + smd_write(smd_channel, &pacmark, sizeof(pacmark)); + smd_write(smd_channel, buffer, count); + + spin_unlock_irqrestore(&smd_lock, flags); + + return 0; +} + int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count) { struct rr_header hdr; uint32_t pacmark; + uint32_t mid; struct rpc_request_hdr *rq = buffer; struct rr_remote_endpoint *r_ept; - unsigned long flags; - int needed; - DEFINE_WAIT(__wait); + int ret; + int total; - /* TODO: fragmentation for large outbound packets */ - if (count > (RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t)) || !count) - return -EINVAL; + if (((rq->prog&0xFFFFFFF0) == RMT_STORAGE_APIPROG_BE32) || + ((rq->prog&0xFFFFFFF0) == RMT_STORAGE_SRV_APIPROG_BE32)) { + printk(KERN_DEBUG + "rpc_write: prog = %x , procedure = %d, type = %d, xid = %d\n" + , be32_to_cpu(rq->prog), be32_to_cpu(rq->procedure) + , be32_to_cpu(rq->type), be32_to_cpu(rq->xid)); + } /* snoop the RPC packet and enforce permissions */ @@ -818,23 +887,21 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count) } else { /* RPC REPLY */ /* TODO: locking */ - if (ept->reply_pid == 0xffffffff) { - printk(KERN_ERR - "rr_write: rejecting unexpected reply\n"); - return -EINVAL; - } - if (ept->reply_xid != rq->xid) { - printk(KERN_ERR - "rr_write: rejecting packet w/ bad xid\n"); - return -EINVAL; + for (ret = 0; ret < MAX_REPLY_ROUTE; ret++) + if (ept->rroute[ret].xid == rq->xid) { + if (ept->rroute[ret].pid == 0xffffffff) + continue; + hdr.dst_pid = ept->rroute[ret].pid; + hdr.dst_cid = ept->rroute[ret].cid; + /* consume this reply */ + ept->rroute[ret].pid = 0xffffffff; + goto found_rroute; } - hdr.dst_pid = ept->reply_pid; - hdr.dst_cid = ept->reply_cid; - - /* consume this reply */ - ept->reply_pid = 0xffffffff; + printk(KERN_ERR "rr_write: rejecting packet w/ bad xid\n"); + return -EINVAL; +found_rroute: IO("REPLY on ept %p to xid=%d @ %d:%08x (%d bytes)\n", ept, be32_to_cpu(rq->xid), hdr.dst_pid, hdr.dst_cid, count); @@ -854,56 +921,36 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count) hdr.version = RPCROUTER_VERSION; hdr.src_pid = ept->pid; hdr.src_cid = ept->cid; - hdr.confirm_rx = 0; - hdr.size = count + sizeof(uint32_t); - for (;;) { - prepare_to_wait(&r_ept->quota_wait, &__wait, - TASK_INTERRUPTIBLE); - spin_lock_irqsave(&r_ept->quota_lock, flags); - if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA) - break; - if (signal_pending(current) && - (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) - break; - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - schedule(); - } - finish_wait(&r_ept->quota_wait, &__wait); + total = count; - if (signal_pending(current) && - (!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) { - spin_unlock_irqrestore(&r_ept->quota_lock, flags); - return -ERESTARTSYS; - } - r_ept->tx_quota_cntr++; - if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA) - hdr.confirm_rx = 1; + mid = atomic_add_return(1, &next_mid) & 0xFF; - /* bump pacmark while interrupts disabled to avoid race - * probably should be atomic op instead - */ - pacmark = PACMARK(count, ++next_pacmarkid, 0, 1); + while (count > 0) { + unsigned xfer; - spin_unlock_irqrestore(&r_ept->quota_lock, flags); + if (count > RPCROUTER_DATASIZE_MAX) + xfer = RPCROUTER_DATASIZE_MAX; + else + xfer = count; - spin_lock_irqsave(&smd_lock, flags); + hdr.confirm_rx = 0; + hdr.size = xfer + sizeof(uint32_t); - needed = sizeof(hdr) + hdr.size; - while (smd_write_avail(smd_channel) < needed) { - spin_unlock_irqrestore(&smd_lock, flags); - msleep(250); - spin_lock_irqsave(&smd_lock, flags); + /* total == count -> must be first packet + * xfer == count -> must be last packet + */ + pacmark = PACMARK(xfer, mid, (total == count), (xfer == count)); + + ret = msm_rpc_write_pkt(ept, r_ept, &hdr, pacmark, buffer, xfer); + if (ret < 0) + return ret; + + buffer += xfer; + count -= xfer; } - /* TODO: deal with full fifo */ - smd_write(smd_channel, &hdr, sizeof(hdr)); - smd_write(smd_channel, &pacmark, sizeof(pacmark)); - smd_write(smd_channel, buffer, count); - - spin_unlock_irqrestore(&smd_lock, flags); - - return count; + return total; } EXPORT_SYMBOL(msm_rpc_write); @@ -1104,20 +1151,30 @@ int __msm_rpc_read(struct msm_rpc_endpoint *ept, *frag_ret = pkt->first; rq = (void*) pkt->first->data; + + if (((rq->prog&0xFFFFFFF0) == RMT_STORAGE_APIPROG_BE32) || + ((rq->prog&0xFFFFFFF0) == RMT_STORAGE_SRV_APIPROG_BE32)) { + printk(KERN_DEBUG + "rpc_read: prog = %x , procedure = %d, type = %d, xid = %d\n" + , be32_to_cpu(rq->prog), be32_to_cpu(rq->procedure) + , be32_to_cpu(rq->type), be32_to_cpu(rq->xid)); + } + if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 0)) { IO("READ on ept %p is a CALL on %08x:%08x proc %d xid %d\n", ept, be32_to_cpu(rq->prog), be32_to_cpu(rq->vers), be32_to_cpu(rq->procedure), be32_to_cpu(rq->xid)); /* RPC CALL */ - if (ept->reply_pid != 0xffffffff) { + if (ept->rroute[ept->next_rroute].pid != 0xffffffff) { printk(KERN_WARNING "rr_read: lost previous reply xid...\n"); } /* TODO: locking? */ - ept->reply_pid = pkt->hdr.src_pid; - ept->reply_cid = pkt->hdr.src_cid; - ept->reply_xid = rq->xid; + ept->rroute[ept->next_rroute].pid = pkt->hdr.src_pid; + ept->rroute[ept->next_rroute].cid = pkt->hdr.src_cid; + ept->rroute[ept->next_rroute].xid = rq->xid; + ept->next_rroute = (ept->next_rroute + 1) & (MAX_REPLY_ROUTE - 1); } #if TRACE_RPC_MSG else if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 1)) diff --git a/arch/arm/mach-msm/smd_rpcrouter.h b/arch/arm/mach-msm/smd_rpcrouter.h index aaf49f72..b86a01f1 100644 --- a/arch/arm/mach-msm/smd_rpcrouter.h +++ b/arch/arm/mach-msm/smd_rpcrouter.h @@ -32,6 +32,7 @@ #define RPCROUTER_VERSION 1 #define RPCROUTER_PROCESSORS_MAX 4 #define RPCROUTER_MSGSIZE_MAX 512 +#define RPCROUTER_DATASIZE_MAX 500 #if defined(CONFIG_ARCH_MSM7X30) #define RPCROUTER_PEND_REPLIES_MAX 32 #endif @@ -50,6 +51,7 @@ #define RPCROUTER_CTRL_CMD_REMOVE_CLIENT 6 #define RPCROUTER_CTRL_CMD_RESUME_TX 7 #define RPCROUTER_CTRL_CMD_EXIT 8 +#define RPCROUTER_CTRL_CMD_PING 9 #define RPCROUTER_DEFAULT_RX_QUOTA 5 @@ -141,6 +143,15 @@ struct rr_remote_endpoint { struct list_head list; }; +struct msm_reply_route { + uint32_t xid; + uint32_t pid; + uint32_t cid; + uint32_t unused; +}; + +#define MAX_REPLY_ROUTE 4 + #if defined(CONFIG_ARCH_MSM7X30) struct msm_rpc_reply { struct list_head list; @@ -183,15 +194,12 @@ struct msm_rpc_endpoint { uint32_t dst_prog; /* be32 */ uint32_t dst_vers; /* be32 */ - /* reply remote address - * if reply_pid == 0xffffffff, none available - * RPC_REPLY writes may only go to the pid/cid/xid of the - * last RPC_CALL we received. + /* RPC_REPLY writes must be routed to the pid/cid of the + * RPC_CALL they are in reply to. Keep a cache of valid + * xid/pid/cid groups. pid 0xffffffff -> not valid. */ - uint32_t reply_pid; - uint32_t reply_cid; - uint32_t reply_xid; /* be32 */ - uint32_t next_pm; /* Pacmark sequence */ + unsigned next_rroute; + struct msm_reply_route rroute[MAX_REPLY_ROUTE]; #if defined(CONFIG_ARCH_MSM7X30) /* reply queue for inbound messages */ @@ -224,6 +232,7 @@ void msm_rpcrouter_exit_devices(void); #if defined(CONFIG_ARCH_MSM7X30) void get_requesting_client(struct msm_rpc_endpoint *ept, uint32_t xid, struct msm_rpc_client_info *clnt_info); +int msm_rpc_clear_netreset(struct msm_rpc_endpoint *ept); #endif extern dev_t msm_rpcrouter_devno; diff --git a/arch/arm/mach-msm/smd_rpcrouter_device.c b/arch/arm/mach-msm/smd_rpcrouter_device.c index bdea3d01..aa2cd45d 100644 --- a/arch/arm/mach-msm/smd_rpcrouter_device.c +++ b/arch/arm/mach-msm/smd_rpcrouter_device.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-msm/smd_rpcrouter_servers.c b/arch/arm/mach-msm/smd_rpcrouter_servers.c index 14dd2f1d..fe6e3c91 100644 --- a/arch/arm/mach-msm/smd_rpcrouter_servers.c +++ b/arch/arm/mach-msm/smd_rpcrouter_servers.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-msm/smd_rpcrouter_xdr.c b/arch/arm/mach-msm/smd_rpcrouter_xdr.c index d6ba2c80..84ec14dc 100644 --- a/arch/arm/mach-msm/smd_rpcrouter_xdr.c +++ b/arch/arm/mach-msm/smd_rpcrouter_xdr.c @@ -78,6 +78,8 @@ #include #include #include +#include +#include #include @@ -421,7 +423,7 @@ int xdr_send_msg(struct msm_rpc_xdr *xdr) void xdr_init(struct msm_rpc_xdr *xdr) { mutex_init(&xdr->out_lock); - mutex_init(&xdr->in_lock); + init_waitqueue_head(&xdr->in_buf_wait_q); xdr->in_buf = NULL; xdr->in_size = 0; @@ -434,7 +436,7 @@ void xdr_init(struct msm_rpc_xdr *xdr) void xdr_init_input(struct msm_rpc_xdr *xdr, void *buf, uint32_t size) { - mutex_lock(&xdr->in_lock); + wait_event(xdr->in_buf_wait_q, !(xdr->in_buf)); xdr->in_buf = buf; xdr->in_size = size; @@ -455,7 +457,7 @@ void xdr_clean_input(struct msm_rpc_xdr *xdr) xdr->in_size = 0; xdr->in_index = 0; - mutex_unlock(&xdr->in_lock); + wake_up(&xdr->in_buf_wait_q); } void xdr_clean_output(struct msm_rpc_xdr *xdr) diff --git a/arch/arm/mach-msm/smd_tty.c b/arch/arm/mach-msm/smd_tty.c index 639989d0..fb2e856f 100644 --- a/arch/arm/mach-msm/smd_tty.c +++ b/arch/arm/mach-msm/smd_tty.c @@ -30,6 +30,7 @@ #include "board-htcleo.h" #define MAX_SMD_TTYS 32 +#define MAX_TTY_BUF_SIZE 2048 static DEFINE_MUTEX(smd_tty_lock); @@ -75,6 +76,9 @@ static void smd_tty_work_func(struct work_struct *work) tty->low_latency = 0; tty_flip_buffer_push(tty); break; + if (avail > MAX_TTY_BUF_SIZE) + avail = MAX_TTY_BUF_SIZE; + } ptr = NULL; diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c index 75ba6c8e..f3120b33 100644 --- a/arch/arm/mach-msm/timer.c +++ b/arch/arm/mach-msm/timer.c @@ -169,18 +169,10 @@ static int msm_timer_set_next_event(unsigned long cycles, clock->last_set = now; clock->alarm_vtime = alarm + clock->offset; late = now - alarm; - if (late >= (int)(-clock->write_delay << clock->shift) && late < DGT_HZ*5) { - static int print_limit = 10; - if (print_limit > 0) { - print_limit--; - printk(KERN_NOTICE "msm_timer_set_next_event(%lu) " - "clock %s, alarm already expired, now %x, " - "alarm %x, late %d%s\n", - cycles, clock->clockevent.name, now, alarm, late, - print_limit ? "" : " stop printing"); - } + if (late >= (int)(-clock->write_delay << clock->shift) && + late < clock->freq*5) return -ETIME; - } + return 0; } @@ -582,9 +574,12 @@ static struct msm_clock msm_clocks[] = { #endif .freq = GPT_HZ, .flags = +#ifdef CONFIG_ARCH_MSM_ARM11 MSM_CLOCK_FLAGS_UNSTABLE_COUNT | MSM_CLOCK_FLAGS_ODD_MATCH_WRITE | - MSM_CLOCK_FLAGS_DELAYED_WRITE_POST, + MSM_CLOCK_FLAGS_DELAYED_WRITE_POST | +#endif + 0, .write_delay = 9, }, [MSM_CLOCK_DGT] = { diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c old mode 100644 new mode 100755 index 6c09d7c6..9e9fb56d --- a/drivers/misc/pmem.c +++ b/drivers/misc/pmem.c @@ -4386,4 +4386,4 @@ static void __exit pmem_exit(void) module_init(pmem_init); module_exit(pmem_exit); -#endif \ No newline at end of file +#endif diff --git a/drivers/mtd/devices/htcleo_nand.c b/drivers/mtd/devices/htcleo_nand.c index 2150bcc2..e4e347e0 100755 --- a/drivers/mtd/devices/htcleo_nand.c +++ b/drivers/mtd/devices/htcleo_nand.c @@ -33,12 +33,15 @@ #include #include #include +#include #include #include #include +unsigned crci_mask; + #if defined(CONFIG_ARCH_MSM7X30) #define MSM_NAND_BASE 0xA0200000 #else @@ -178,6 +181,11 @@ static void *msm_nand_get_dma_buffer(struct msm_nand_chip *chip, size_t size) do { free_index = __ffs(free_bitmask); current_need_mask = need_mask << free_index; + + if (size + free_index * MSM_NAND_DMA_BUFFER_SLOTS >= + MSM_NAND_DMA_BUFFER_SIZE) + return NULL; + if ((bitmask & current_need_mask) == 0) { old_bitmask = atomic_cmpxchg(&chip->dma_buffer_busy, @@ -262,7 +270,7 @@ uint32_t flash_read_id(struct msm_nand_chip *chip) dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); @@ -306,7 +314,7 @@ int flash_read_config(struct msm_nand_chip *chip) dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); @@ -346,7 +354,7 @@ unsigned flash_rd_reg(struct msm_nand_chip *chip, unsigned addr) dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); rv = dma_buffer->data; @@ -379,7 +387,7 @@ void flash_wr_reg(struct msm_nand_chip *chip, unsigned addr, unsigned val) dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); @@ -750,7 +758,7 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_o dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR( + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR( msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); @@ -893,13 +901,13 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_o dma_buffer->data.result[2].buffer_status, dma_buffer->data.result[3].flash_status, dma_buffer->data.result[3].buffer_status, + dma_buffer->data.result[4].flash_status, dma_buffer->data.result[4].buffer_status, - dma_buffer->data.result[4].buffer_status, - dma_buffer->data.result[5].buffer_status, + dma_buffer->data.result[5].flash_status, dma_buffer->data.result[5].buffer_status, + dma_buffer->data.result[6].flash_status, dma_buffer->data.result[6].buffer_status, - dma_buffer->data.result[6].buffer_status, - dma_buffer->data.result[7].buffer_status, + dma_buffer->data.result[7].flash_status, dma_buffer->data.result[7].buffer_status); } #endif @@ -1364,7 +1372,7 @@ msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP; dsb(); - msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); + msm_dmov_exec_cmd(chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); /* if any of the writes failed (0x10), or there was a @@ -1576,7 +1584,7 @@ msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr) dsb(); msm_dmov_exec_cmd( - chip->dma_channel, DMOV_CMD_PTR_LIST | + chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); @@ -1727,7 +1735,7 @@ msm_nand_block_isbad(struct mtd_info *mtd, loff_t ofs) dma_buffer->cmd) >> 3) | CMD_PTR_LP; dsb(); - msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST | + msm_dmov_exec_cmd(chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr))); dsb(); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 99bbd282..e1f2111c 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -697,9 +697,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; - u32 *buffer, *dst; - u32 __iomem *src; - int c, i, cnt = 0, err = 0; + u8 *buffer, *dst; + u8 __iomem *src; + int c, cnt = 0, err = 0; unsigned long total_size; if (!info || ! info->screen_base) @@ -730,7 +730,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) if (!buffer) return -ENOMEM; - src = (u32 __iomem *) (info->screen_base + p); + src = (u8 __iomem *) (info->screen_base + p); if (info->fbops->fb_sync) info->fbops->fb_sync(info); @@ -738,17 +738,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) while (count) { c = (count > PAGE_SIZE) ? PAGE_SIZE : count; dst = buffer; - for (i = c >> 2; i--; ) - *dst++ = fb_readl(src++); - if (c & 3) { - u8 *dst8 = (u8 *) dst; - u8 __iomem *src8 = (u8 __iomem *) src; - - for (i = c & 3; i--;) - *dst8++ = fb_readb(src8++); - - src = (u32 __iomem *) src8; - } + fb_memcpy_fromfb(dst, src, c); + dst += c; + src += c; if (copy_to_user(buf, buffer, c)) { err = -EFAULT; @@ -772,9 +764,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) struct inode *inode = file->f_path.dentry->d_inode; int fbidx = iminor(inode); struct fb_info *info = registered_fb[fbidx]; - u32 *buffer, *src; - u32 __iomem *dst; - int c, i, cnt = 0, err = 0; + u8 *buffer, *src; + u8 __iomem *dst; + int c, cnt = 0, err = 0; unsigned long total_size; if (!info || !info->screen_base) @@ -811,7 +803,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) if (!buffer) return -ENOMEM; - dst = (u32 __iomem *) (info->screen_base + p); + dst = (u8 __iomem *) (info->screen_base + p); if (info->fbops->fb_sync) info->fbops->fb_sync(info); @@ -825,19 +817,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) break; } - for (i = c >> 2; i--; ) - fb_writel(*src++, dst++); - - if (c & 3) { - u8 *src8 = (u8 *) src; - u8 __iomem *dst8 = (u8 __iomem *) dst; - - for (i = c & 3; i--; ) - fb_writeb(*src8++, dst8++); - - dst = (u32 __iomem *) dst8; - } - + fb_memcpy_tofb(dst, src, c); + dst += c; + src += c; *ppos += c; buf += c; cnt += c; @@ -877,13 +859,13 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var) if ((err = info->fbops->fb_pan_display(var, info))) return err; - info->var.xoffset = var->xoffset; - info->var.yoffset = var->yoffset; - if (var->vmode & FB_VMODE_YWRAP) - info->var.vmode |= FB_VMODE_YWRAP; - else - info->var.vmode &= ~FB_VMODE_YWRAP; - return 0; + info->var.xoffset = var->xoffset; + info->var.yoffset = var->yoffset; + if (var->vmode & FB_VMODE_YWRAP) + info->var.vmode |= FB_VMODE_YWRAP; + else + info->var.vmode &= ~FB_VMODE_YWRAP; + return 0; } static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var, @@ -1438,6 +1420,7 @@ static const struct file_operations fb_fops = { #ifdef CONFIG_FB_DEFERRED_IO .fsync = fb_deferred_io_fsync, #endif + .llseek = default_llseek, }; struct class *fb_class; @@ -1468,16 +1451,70 @@ static int fb_check_foreignness(struct fb_info *fi) return 0; } -static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw) +static bool apertures_overlap(struct aperture *gen, struct aperture *hw) { /* is the generic aperture base the same as the HW one */ - if (gen->aperture_base == hw->aperture_base) + if (gen->base == hw->base) return true; /* is the generic aperture base inside the hw base->hw base+size */ - if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size) + if (gen->base > hw->base && gen->base < hw->base + hw->size) return true; return false; } + +static bool fb_do_apertures_overlap(struct apertures_struct *gena, + struct apertures_struct *hwa) +{ + int i, j; + if (!hwa || !gena) + return false; + + for (i = 0; i < hwa->count; ++i) { + struct aperture *h = &hwa->ranges[i]; + for (j = 0; j < gena->count; ++j) { + struct aperture *g = &gena->ranges[j]; + printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n", + (unsigned long long)g->base, + (unsigned long long)g->size, + (unsigned long long)h->base, + (unsigned long long)h->size); + if (apertures_overlap(g, h)) + return true; + } + } + + return false; +} + +#define VGA_FB_PHYS 0xA0000 +void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ + int i; + + /* check all firmware fbs and kick off if the base addr overlaps */ + for (i = 0 ; i < FB_MAX; i++) { + struct apertures_struct *gen_aper; + if (!registered_fb[i]) + continue; + + if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) + continue; + + gen_aper = registered_fb[i]->apertures; + if (fb_do_apertures_overlap(gen_aper, a) || + (primary && gen_aper && gen_aper->count && + gen_aper->ranges[0].base == VGA_FB_PHYS)) { + + printk(KERN_ERR "fb: conflicting fb hw usage " + "%s vs %s - removing generic driver\n", + name, registered_fb[i]->fix.id); + unregister_framebuffer(registered_fb[i]); + } + } +} +EXPORT_SYMBOL(remove_conflicting_framebuffers); + /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig old mode 100644 new mode 100755 index 5f445724..46921131 --- a/drivers/video/msm/Kconfig +++ b/drivers/video/msm/Kconfig @@ -1,3 +1,26 @@ +config FB_MSM + tristate "MSM Framebuffer" + depends on FB && ARCH_MSM + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + +config FB_MSM_MDP_PPP + bool "MSM MDP PPP" + depends on FB_MSM_LEGACY_MDP + default y + +config FB_MSM_LCDC + bool "Support for integrated LCD controller in MDP3/4" + depends on FB_MSM && (MSM_MDP31 || MSM_MDP302 || MSM_MDP40) + default y + +config FB_MSM_MDDI + bool "Support for MSM MDDI controllers" + depends on FB_MSM + default y + config FB_MSM tristate depends on FB && ARCH_MSM @@ -6,43 +29,35 @@ config FB_MSM select FB_CFB_IMAGEBLIT default y +config FB_MSM_LEGACY_MDP + bool "MSM Legacy MDP (qsd8k)" + depends on FB_MSM && (MSM_MDP30 || MSM_MDP31 || MSM_MDP302) + default y + +config FB_MSM_MDP_PPP + bool "MSM MDP PPP" + depends on FB_MSM_LEGACY_MDP + default y + config FB_MSM_LCDC - bool "Support for integrated LCD controller in qsd8x50 and MSM7x27" - depends on FB_MSM && (MSM_MDP31 || MSM_MDP302) + bool "Support for integrated LCD controller in qsd8x50 ,MSM7x27 and MSM7x30" + depends on FB_MSM && (MSM_MDP31 || MSM_MDP302 || MSM_MDP40) default y -config FB_MSM_TVOUT - bool "Support for TV-Out in qsd8x50" - depends on FB_MSM && MSM_MDP31 - default n - -config FB_MSM_OVERLAY - bool "Support for overlay in MSM7X30" - depends on FB_MSM && MSM_MDP40 +config FB_MSM_MDDI + bool "Support for MSM MDDI controllers" + depends on FB_MSM default y -config FB_MSM_DTV - depends on FB_MSM_OVERLAY - bool +config FB_MSM_MDDI_EPSON + bool "Support for Epson MDDI panels" + depends on FB_MSM_MDDI default n -config MSM_ROTATOR - tristate "MSM Offline Image Rotator Driver" - depends on ARCH_MSM7X30 && ANDROID_PMEM - default y - help - This driver provides support for the image rotator HW block in the - MSM 7x30 SoC. - -config MSM_ROTATOR_USE_IMEM - bool "Enable rotator driver to use iMem" - depends on MSM_ROTATOR - default y - help - This option enables the msm_rotator driver to use the move efficient - iMem. Some MSM platforms may not have iMem available for the rotator - block. Or some systems may want the iMem to be dedicated to a - different function. +config FB_MSM_MDDI_NOVTEC + bool "Support for Novtec MDDI panels" + depends on FB_MSM_MDDI + default n config MSM_HDMI bool "Support for HDMI in QCT platform" diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile old mode 100644 new mode 100755 index b7380f17..4146ff66 --- a/drivers/video/msm/Makefile +++ b/drivers/video/msm/Makefile @@ -14,6 +14,8 @@ obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay.o obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay_mddi.o obj-$(CONFIG_MSM_MDP40) += msm_rotator.o +obj-$(CONFIG_FB_MSM_LEGACY_MDP) += mdp_hw_legacy.o + obj-$(CONFIG_MSM_MDP22) += mdp_ppp22.o obj-$(CONFIG_MSM_MDP30) += mdp_ppp22.o obj-$(CONFIG_MSM_MDP302)+= mdp_ppp22.o @@ -25,11 +27,10 @@ obj-y += mddi.o # MDDI client/panel drivers # -obj-y += mddi_client_dummy.o +obj-y += mddi_client_simple.o +obj-y += mddi_client_toshiba.o obj-y += mddi_client_epson.o obj-y += mddi_client_novb9f6_5582.o # MDP LCD controller driver obj-$(CONFIG_FB_MSM_LCDC) += mdp_lcdc.o -obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o tvfb.o - diff --git a/drivers/video/msm/mddi.c b/drivers/video/msm/mddi.c index 0c39572c..7dbf8a6c 100644 --- a/drivers/video/msm/mddi.c +++ b/drivers/video/msm/mddi.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include "mddi_hw.h" @@ -106,7 +106,9 @@ struct mddi_info { }; static void mddi_init_rev_encap(struct mddi_info *mddi); +/* FIXME: Workaround for Novatek static void mddi_skew_calibration(struct mddi_info *mddi); +*/ #define mddi_readl(r) readl(mddi->base + (MDDI_##r)) #define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r)) @@ -204,10 +206,8 @@ static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask); static void mddi_handle_rev_data_avail(struct mddi_info *mddi) { - union mddi_rev *rev = mddi->rev_data; uint32_t rev_data_count; uint32_t rev_crc_err_count; - int i; struct reg_read_info *ri; size_t prev_offset; uint16_t length; @@ -242,6 +242,8 @@ static void mddi_handle_rev_data_avail(struct mddi_info *mddi) return; if (mddi_debug_flags & 1) { + int i; + union mddi_rev *rev = mddi->rev_data; printk(KERN_INFO "INT %x, STAT %x, CURR_REV_PTR %x\n", mddi_readl(INT), mddi_readl(STAT), mddi_readl(CURR_REV_PTR)); @@ -355,7 +357,7 @@ static irqreturn_t mddi_isr(int irq, void *data) static long mddi_wait_interrupt_timeout(struct mddi_info *mddi, uint32_t intmask, int timeout) { - unsigned long irq_flags; + unsigned long irq_flags=0; spin_lock_irqsave(&mddi->int_lock, irq_flags); mddi->got_int &= ~intmask; @@ -369,7 +371,7 @@ static long mddi_wait_interrupt_timeout(struct mddi_info *mddi, static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask) { if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0) - printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout " + printk(KERN_INFO "mddi_wait_interrupt %d, timeout " "waiting for %x, INT = %x, STAT = %x gotint = %x\n", current->pid, intmask, mddi_readl(INT), mddi_readl(STAT), mddi->got_int); @@ -399,7 +401,10 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi) mddi_writel(0x0001, VERSION); mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS); mddi_writel(0x0003, SPM); /* subframes per media */ - mddi_writel(0x0005, TA1_LEN); + if (mddi->type == MSM_MDP_MDDI_TYPE_II) + mddi_writel(0x00C8, TA1_LEN); + else + mddi_writel(0x0005, TA1_LEN); mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN); mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */ mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV); @@ -431,7 +436,7 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi) mddi_writel(0x0050, DRIVE_LO); mddi_writel(0x00320000, PAD_IO_CTL); if (mddi->type == MSM_MDP_MDDI_TYPE_II) - mddi_writel(0x40884020, PAD_CAL); + mddi_writel(0x40880020, PAD_CAL); else mddi_writel(0x00220020, PAD_CAL); #else @@ -469,7 +474,7 @@ static void mddi_suspend(struct msm_mddi_client_data *cdata) mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); /* turn off the clock */ clk_disable(mddi->clk); -#if CONFIG_MSM_MDP40 +#ifdef CONFIG_MSM_MDP40 clk_disable(mdp_clk); #endif wake_unlock(&mddi->idle_lock); @@ -484,7 +489,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) /* turn on the client */ if (mddi->power_client) mddi->power_client(&mddi->client_data, 1); -#if CONFIG_MSM_MDP40 +#ifdef CONFIG_MSM_MDP40 clk_enable(mdp_clk); #endif /* turn on the clock */ @@ -498,7 +503,8 @@ static void mddi_resume(struct msm_mddi_client_data *cdata) */ mddi_writel(mddi->int_enable, INTEN); mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD); - mddi_writel(MDDI_CMD_SEND_RTD, CMD); + if (mddi->type == MSM_MDP_MDDI_TYPE_I) + mddi_writel(MDDI_CMD_SEND_RTD, CMD); mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); mddi_set_auto_hibernate(&mddi->client_data, 1); wake_unlock(&mddi->idle_lock); @@ -689,7 +695,7 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) struct reg_read_info ri; unsigned s; int retry_count = 2; - unsigned long irq_flags; + unsigned long irq_flags=0; mutex_lock(&mddi->reg_read_lock); @@ -720,6 +726,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) do { init_completion(&ri.done); + if (mddi->type == MSM_MDP_MDDI_TYPE_II) + mddi_set_auto_hibernate(&mddi->client_data, 0); + mddi_writel(MDDI_CMD_SEND_RTD, CMD); mddi->reg_read = &ri; mddi_writel(mddi->reg_read_addr, PRI_PTR); @@ -732,10 +741,14 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) /* while((s & MDDI_STAT_PRI_LINK_LIST_DONE) == 0){ */ /* s = mddi_readl(STAT); */ /* } */ - - /* Enable Periodic Reverse Encapsulation. */ - mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); - mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); + if (mddi->type == MSM_MDP_MDDI_TYPE_II) { + mddi_writel(MDDI_CMD_SEND_REV_ENCAP, CMD); + mddi_wait_interrupt(mddi, MDDI_INT_REV_DATA_AVAIL); + } else { + /* Enable Periodic Reverse Encapsulation. */ + mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD); + mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND); + } if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 && !ri.done.done) { printk(KERN_INFO "mddi_remote_read(%x) timeout " @@ -763,6 +776,8 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg) "MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x " "curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT), mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR)); + if (mddi->type == MSM_MDP_MDDI_TYPE_II) + mddi_set_auto_hibernate(&mddi->client_data, 1); } while (retry_count-- > 0); /* Disable Periodic Reverse Encapsulation. */ mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD); @@ -830,7 +845,7 @@ static int __init mddi_rev_data_setup(struct mddi_info *mddi) sizeof(*mddi->reg_write_data); return 0; } - +/* FIXME: Workaround for Novatek static void mddi_skew_calibration(struct mddi_info *mddi) { struct msm_mddi_platform_data *pdata = mddi->client_pdev.dev.platform_data; @@ -842,6 +857,7 @@ static void mddi_skew_calibration(struct mddi_info *mddi) clk_set_rate( mddi->clk, pdata->clk_rate); mdelay(1); } +*/ static int __init mddi_probe(struct platform_device *pdev) { @@ -871,7 +887,7 @@ static int __init mddi_probe(struct platform_device *pdev) printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base, mddi->irq); mddi->power_client = pdata->power_client; - if (pdata->type != NULL) + if ((pdata->type != NULL) && (pdata->type != MSM_MDP_MDDI_TYPE_I)) mddi->type = pdata->type; mutex_init(&mddi->reg_write_lock); diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/msm/mddi_client_dummy.c deleted file mode 100644 index ebbae878..00000000 --- a/drivers/video/msm/mddi_client_dummy.c +++ /dev/null @@ -1,97 +0,0 @@ -/* drivers/video/msm_fb/mddi_client_dummy.c - * - * Support for "dummy" mddi client devices which require no - * special initialization code. - * - * Copyright (C) 2007 Google Incorporated - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -#include - -struct panel_info { - struct platform_device pdev; - struct msm_panel_data panel_data; -}; - -static int mddi_dummy_suspend(struct msm_panel_data *panel_data) -{ - return 0; -} - -static int mddi_dummy_resume(struct msm_panel_data *panel_data) -{ - return 0; -} - -static int mddi_dummy_blank(struct msm_panel_data *panel_data) -{ - return 0; -} - -static int mddi_dummy_unblank(struct msm_panel_data *panel_data) -{ - return 0; -} - -static int mddi_dummy_probe(struct platform_device *pdev) -{ - struct msm_mddi_client_data *client_data = pdev->dev.platform_data; - struct panel_info *panel = - kzalloc(sizeof(struct panel_info), GFP_KERNEL); - int ret; - if (!panel) - return -ENOMEM; - platform_set_drvdata(pdev, panel); - panel->panel_data.suspend = mddi_dummy_suspend; - panel->panel_data.resume = mddi_dummy_resume; - panel->panel_data.blank = mddi_dummy_blank; - panel->panel_data.unblank = mddi_dummy_unblank; - panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES; - panel->pdev.name = "msm_panel"; - panel->pdev.id = pdev->id; - platform_device_add_resources(&panel->pdev, - client_data->fb_resource, 1); - panel->panel_data.fb_data = client_data->private_client_data; - panel->pdev.dev.platform_data = &panel->panel_data; - ret = platform_device_register(&panel->pdev); - if (ret) { - kfree(panel); - return ret; - } - return 0; -} - -static int mddi_dummy_remove(struct platform_device *pdev) -{ - struct panel_info *panel = platform_get_drvdata(pdev); - kfree(panel); - return 0; -} - -static struct platform_driver mddi_client_dummy = { - .probe = mddi_dummy_probe, - .remove = mddi_dummy_remove, - .driver = { .name = "mddi_c_dummy" }, -}; - -static int __init mddi_client_dummy_init(void) -{ - platform_driver_register(&mddi_client_dummy); - return 0; -} - -module_init(mddi_client_dummy_init); - diff --git a/drivers/video/msm/mddi_client_epson.c b/drivers/video/msm/mddi_client_epson.c index 577b09c8..d5ea5e3e 100644 --- a/drivers/video/msm/mddi_client_epson.c +++ b/drivers/video/msm/mddi_client_epson.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include static DECLARE_WAIT_QUEUE_HEAD(epson_vsync_wait); diff --git a/drivers/video/msm/mddi_client_novb9f6_5582.c b/drivers/video/msm/mddi_client_novb9f6_5582.c index defd92de..1d8030b9 100644 --- a/drivers/video/msm/mddi_client_novb9f6_5582.c +++ b/drivers/video/msm/mddi_client_novb9f6_5582.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include static DECLARE_WAIT_QUEUE_HEAD(novtec_vsync_wait); @@ -145,7 +147,6 @@ static irqreturn_t novtec_vsync_interrupt(int irq, void *data) panel->novtec_got_int = 1; if (panel->novtec_callback) { - mdelay(3); panel->novtec_callback->func(panel->novtec_callback); panel->novtec_callback = 0; } diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c index c9e93494..f239f4a2 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/msm/mddi_client_nt35399.c @@ -21,6 +21,7 @@ #include #include #include +#include #include static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait); diff --git a/drivers/video/msm/mddi_client_simple.c b/drivers/video/msm/mddi_client_simple.c new file mode 100644 index 00000000..b27a809d --- /dev/null +++ b/drivers/video/msm/mddi_client_simple.c @@ -0,0 +1,236 @@ +/* drivers/video/msm_fb/mddi_client_simple.c + * + * Support for simple mddi client devices which require no special + * initialization code except for what may be provided in the board file. + * If the clients do not provide board specific code, this driver's + * panel operations are no-ops. + * + * Copyright (C) 2007-2010, Google Incorporated + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +struct panel_info { + struct platform_device pdev; + struct msm_mddi_client_data *client_data; + struct msm_panel_data panel_data; + struct msmfb_callback *fb_callback; + wait_queue_head_t vsync_wait; + int got_vsync; + int irq; +}; + +#define to_panel_info(pd) container_of((pd), struct panel_info, panel_data) + +static void mddi_simple_request_vsync(struct msm_panel_data *panel_data, + struct msmfb_callback *callback) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + + panel->fb_callback = callback; + if (panel->got_vsync) { + panel->got_vsync = 0; + client_data->activate_link(client_data); /* clears interrupt */ + } +} + +static void mddi_simple_wait_vsync(struct msm_panel_data *panel_data) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + int ret; + + if (panel->got_vsync) { + panel->got_vsync = 0; + client_data->activate_link(client_data); /* clears interrupt */ + } + + ret = wait_event_timeout(panel->vsync_wait, panel->got_vsync, HZ/2); + if (!ret && !panel->got_vsync) + pr_err("mddi_client_simple: timeout waiting for vsync\n"); + + panel->got_vsync = 0; + /* interrupt clears when screen dma starts */ +} + + +static int mddi_simple_suspend(struct msm_panel_data *panel_data) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + struct msm_mddi_bridge_platform_data *bridge_data = + client_data->private_client_data; + int ret; + + if (!bridge_data->uninit) + return 0; + + ret = bridge_data->uninit(bridge_data, client_data); + if (ret) { + pr_info("%s: non zero return from uninit\n", __func__); + return ret; + } + client_data->suspend(client_data); + return 0; +} + +static int mddi_simple_resume(struct msm_panel_data *panel_data) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + struct msm_mddi_bridge_platform_data *bridge_data = + client_data->private_client_data; + + if (!bridge_data->init) + return 0; + + client_data->resume(client_data); + return bridge_data->init(bridge_data, client_data); +} + +static int mddi_simple_blank(struct msm_panel_data *panel_data) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + struct msm_mddi_bridge_platform_data *bridge_data = + client_data->private_client_data; + + if (!bridge_data->blank) + return 0; + return bridge_data->blank(bridge_data, client_data); +} + +static int mddi_simple_unblank(struct msm_panel_data *panel_data) +{ + struct panel_info *panel = to_panel_info(panel_data); + struct msm_mddi_client_data *client_data = panel->client_data; + struct msm_mddi_bridge_platform_data *bridge_data = + client_data->private_client_data; + + if (!bridge_data->unblank) + return 0; + return bridge_data->unblank(bridge_data, client_data); +} + +static irqreturn_t handle_vsync_irq(int irq, void *data) +{ + struct panel_info *panel = data; + + panel->got_vsync = 1; + if (panel->fb_callback) { + panel->fb_callback->func(panel->fb_callback); + panel->fb_callback = NULL; + } + + wake_up(&panel->vsync_wait); + return IRQ_HANDLED; +} + +static int mddi_simple_probe(struct platform_device *pdev) +{ + struct msm_mddi_client_data *client_data = pdev->dev.platform_data; + struct msm_mddi_bridge_platform_data *bridge_data = + client_data->private_client_data; + struct panel_info *panel; + int ret; + + pr_debug("%s()\n", __func__); + + panel = kzalloc(sizeof(struct panel_info), GFP_KERNEL); + if (!panel) + return -ENOMEM; + + platform_set_drvdata(pdev, panel); + + init_waitqueue_head(&panel->vsync_wait); + + panel->irq = platform_get_irq_byname(pdev, "vsync"); + if (panel->irq >= 0) { + ret = request_irq(panel->irq, handle_vsync_irq, + IRQF_TRIGGER_RISING, "mddi_c_simple_vsync", + panel); + if (ret) { + pr_err("%s: request vsync irq %d failed (%d)\n", + __func__, panel->irq, ret); + goto err_req_irq; + } + + panel->panel_data.wait_vsync = mddi_simple_wait_vsync; + panel->panel_data.request_vsync = mddi_simple_request_vsync; + } + + panel->client_data = client_data; + panel->panel_data.suspend = mddi_simple_suspend; + panel->panel_data.resume = mddi_simple_resume; + panel->panel_data.blank = mddi_simple_blank; + panel->panel_data.unblank = mddi_simple_unblank; + panel->panel_data.caps = bridge_data->caps; + panel->panel_data.fb_data = &bridge_data->fb_data; + + panel->pdev.name = "msm_panel"; + panel->pdev.id = pdev->id; + platform_device_add_resources(&panel->pdev, + client_data->fb_resource, 1); + panel->pdev.dev.platform_data = &panel->panel_data; + + if (bridge_data->init) + bridge_data->init(bridge_data, client_data); + + ret = platform_device_register(&panel->pdev); + if (ret) { + pr_err("%s: Can't register platform device\n", __func__); + goto err_plat_dev_reg; + } + + return 0; + +err_plat_dev_reg: + if (panel->irq >= 0) + free_irq(panel->irq, panel); +err_req_irq: + platform_set_drvdata(pdev, NULL); + kfree(panel); + return ret; +} + +static int mddi_simple_remove(struct platform_device *pdev) +{ + struct panel_info *panel = platform_get_drvdata(pdev); + kfree(panel); + return 0; +} + +static struct platform_driver mddi_client_simple = { + .probe = mddi_simple_probe, + .remove = mddi_simple_remove, + .driver = { + .owner = THIS_MODULE, + .name = "mddi_c_simple" + }, +}; + +static int __init mddi_client_simple_init(void) +{ + platform_driver_register(&mddi_client_simple); + return 0; +} + +module_init(mddi_client_simple_init); diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c index 71048e78..f9bc932a 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/msm/mddi_client_toshiba.c @@ -21,6 +21,7 @@ #include #include #include +#include #include diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/msm/mddi_hw.h index 16e80126..2e1dd206 100644 --- a/drivers/video/msm/mddi_hw.h +++ b/drivers/video/msm/mddi_hw.h @@ -53,8 +53,9 @@ #define MDDI_MF_CNT 0x0084 #define MDDI_CURR_REV_PTR 0x0088 #define MDDI_CORE_VER 0x008c -#define MDDI_PAD_IO_CTL 0x00a0 -#define MDDI_PAD_CAL 0x00a4 +#define MDDI_SF_LEN_CTL_REG 0x0094 +#define MDDI_PAD_IO_CTL 0x00a0 +#define MDDI_PAD_CAL 0x00a4 #define MDDI_INT_PRI_PTR_READ 0x0001 #define MDDI_INT_SEC_PTR_READ 0x0002 @@ -131,8 +132,10 @@ #define MDDI_HOST_TA2_LEN 0x000c #endif -#if defined (CONFIG_ARCH_QSD8X50) || defined (CONFIG_ARCH_MSM7X30) +#if defined (CONFIG_ARCH_QSD8X50) #define MDDI_HOST_REV_RATE_DIV 0x0004 +#elif defined (CONFIG_ARCH_MSM7X30) +#define MDDI_HOST_REV_RATE_DIV 0x0010 #else #define MDDI_HOST_REV_RATE_DIV 0x0002 #endif diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c index 5e21cf86..0d17f68b 100644 --- a/drivers/video/msm/mdp.c +++ b/drivers/video/msm/mdp.c @@ -21,10 +21,10 @@ #include #include #include +#include #include #include #include -#include #include #include @@ -36,10 +36,16 @@ struct class *mdp_class; +#ifdef CONFIG_MSM_HDMI +/* Used to report LCDC underflows */ +void reportUnderflow(void); +#endif + #define MDP_CMD_DEBUG_ACCESS_BASE (0x10000) static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue); static unsigned int mdp_irq_mask; +static unsigned int mdp_dma_timer_enable = 0; struct clk *mdp_clk_to_disable_later = 0; static struct mdp_blit_req *timeout_req; #ifdef CONFIG_FB_MSM_OVERLAY @@ -53,7 +59,19 @@ extern void mdp4_mddi_overlay(void *priv, uint32_t addr, uint32_t stride, uint32_t y); #include "mdp4.h" #endif -DEFINE_MUTEX(mdp_mutex); + + +static void mdp_do_standby_timer(unsigned long data) +{ + struct mdp_info *mdp = (struct mdp_info *) data; + if (!mdp_irq_mask) { + clk_set_rate(mdp->ebi1_clk, 0); + mdp->state |= MDP_STATE_STANDBY; + } else { + mod_timer(&mdp->standby_timer, + jiffies + msecs_to_jiffies(200)); + } +} static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) { @@ -69,7 +87,17 @@ static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) if (!mdp_irq_mask) { clk_enable(mdp->clk); enable_irq(mdp->irq); - clk_set_rate(mdp->ebi1_clk, 128000000); + if (mdp->state & MDP_STATE_STANDBY) { +#ifdef CONFIG_MSM_MDP40 + clk_set_rate(mdp->ebi1_clk, 153000000); +#else + clk_set_rate(mdp->ebi1_clk, 128000000); +#endif + mdp->state &= ~MDP_STATE_STANDBY; + } else { + del_timer_sync(&mdp->standby_timer); + barrier(); + } } /* clear out any previous irqs for the requested mask*/ @@ -84,7 +112,7 @@ static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask) { - unsigned long flags; + unsigned long flags=0; int ret; spin_lock_irqsave(&mdp->lock, flags); @@ -111,14 +139,16 @@ static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) disable_irq_nosync(mdp->irq); if (mdp->clk) clk_disable(mdp->clk); - clk_set_rate(mdp->ebi1_clk, 0); + if (!(mdp->state & MDP_STATE_STANDBY)) + mod_timer(&mdp->standby_timer, + jiffies + msecs_to_jiffies(200)); } return 0; } int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) { - unsigned long irq_flags; + unsigned long irq_flags=0; int ret; spin_lock_irqsave(&mdp->lock, irq_flags); @@ -130,7 +160,7 @@ int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask) static irqreturn_t mdp_isr(int irq, void *data) { uint32_t status; - unsigned long irq_flags; + unsigned long irq_flags=0; struct mdp_info *mdp = data; int i; @@ -139,13 +169,22 @@ static irqreturn_t mdp_isr(int irq, void *data) status = mdp_readl(mdp, MDP_INTR_STATUS); mdp_writel(mdp, status, MDP_INTR_CLEAR); - -#if defined(CONFIG_MACH_HTCLEO) - status &= ~0x10000; // Cotulla -#endif - // pr_info("%s: status=%08x (irq_mask=%08x)\n", __func__, status, // mdp_irq_mask); + + if (mdp_dma_timer_enable) { + del_timer_sync(&mdp->dma_timer); + mdp_dma_timer_enable = 0; + } + +#ifdef CONFIG_MSM_HDMI + if (status & MDP_LCDC_UNDERFLOW) + { + pr_err("%s: LCDC Underflow\n", __func__); + reportUnderflow(); + } +#endif + status &= ~0x10000; // Cotulla status &= mdp_irq_mask; #ifdef CONFIG_MSM_MDP40 if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) { @@ -168,9 +207,9 @@ static irqreturn_t mdp_isr(int irq, void *data) } } - if (status & DL0_ROI_DONE) - wake_up(&mdp_ppp_waitqueue); - +#ifndef CONFIG_MSM_MDP40 + mdp_ppp_handle_isr(mdp, status); +#endif if (status) locked_disable_mdp_irq(mdp, status); @@ -178,10 +217,43 @@ static irqreturn_t mdp_isr(int irq, void *data) return IRQ_HANDLED; } +static void mdp_do_dma_timer(unsigned long data) +{ + uint32_t status; + struct mdp_info *mdp = (struct mdp_info *) data; + unsigned long irq_flags=0; + int i; + + spin_lock_irqsave(&mdp->lock, irq_flags); + + status = mdp_readl(mdp, MDP_INTR_STATUS); + mdp_writel(mdp, mdp_irq_mask, MDP_INTR_CLEAR); + + for (i = 0; i < MSM_MDP_NUM_INTERFACES; ++i) { + struct mdp_out_interface *out_if = &mdp->out_if[i]; + if (mdp_irq_mask & out_if->dma_mask) { + if (out_if->dma_cb) { + out_if->dma_cb->func(out_if->dma_cb); + out_if->dma_cb = NULL; + } + wake_up(&out_if->dma_waitqueue); + } + if (mdp_irq_mask & out_if->irq_mask) { + out_if->irq_cb->func(out_if->irq_cb); + out_if->irq_cb = NULL; + } + } + + locked_disable_mdp_irq(mdp, mdp_irq_mask); + + spin_unlock_irqrestore(&mdp->lock, irq_flags); + +} + static uint32_t mdp_check_mask(struct mdp_info *mdp, uint32_t mask) { uint32_t ret; - unsigned long irq_flags; + unsigned long irq_flags=0; spin_lock_irqsave(&mdp->lock, irq_flags); ret = mdp_irq_mask & mask; @@ -189,10 +261,29 @@ static uint32_t mdp_check_mask(struct mdp_info *mdp, uint32_t mask) return ret; } -static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq) +void mdp_dump_blit(struct mdp_blit_req *req) +{ + pr_info("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__, + req->src.width, req->src.height, req->src.format, + req->src.offset, req->src.memory_id); + pr_info("%s: dst: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__, + req->dst.width, req->dst.height, req->dst.format, + req->dst.offset, req->dst.memory_id); + pr_info("%s: src_rect: x=%d y=%d w=%d h=%d\n", __func__, + req->src_rect.x, req->src_rect.y, req->src_rect.w, + req->src_rect.h); + pr_info("%s: dst_rect: x=%d y=%d w=%d h=%d\n", __func__, + req->dst_rect.x, req->dst_rect.y, req->dst_rect.w, + req->dst_rect.h); + pr_info("%s: alpha=0x%08x\n", __func__, req->alpha); + pr_info("%s: transp_max=0x%08x\n", __func__, req->transp_mask); + pr_info("%s: flags=%08x\n", __func__, req->flags); +} + +int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq) { int ret = 0; - unsigned long irq_flags; + unsigned long irq_flags=0; // pr_info("%s: WAITING for 0x%x\n", __func__, mask); wait_event_timeout(*wq, !mdp_check_mask(mdp, mask), HZ); @@ -214,7 +305,7 @@ static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq) return ret; } -void mdp_dma_wait(struct mdp_device *mdp_dev, int interface) +static void mdp_dma_wait(struct mdp_device *mdp_dev, int interface) { #define MDP_MAX_TIMEOUTS 20 static int timeout_count; @@ -247,54 +338,42 @@ void mdp_dma_wait(struct mdp_device *mdp_dev, int interface) BUG(); } } - +/* static int mdp_ppp_wait(struct mdp_info *mdp) { return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue); } - +*/ +#ifndef CONFIG_MSM_MDP40 static void mdp_dmas_to_mddi(void *priv, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y) { struct mdp_info *mdp = priv; uint32_t dma2_cfg; - uint32_t video_packet_parameter; + uint32_t video_packet_parameter = 0; uint16_t ld_param = 1; + dma2_cfg = DMA_PACK_TIGHT | + DMA_PACK_ALIGN_LSB | + DMA_OUT_SEL_AHB | + DMA_IBUF_NONCONTIGUOUS; - if(machine_is_htcleo()) { - dma2_cfg = DMA_PACK_ALIGN_MSB | - DMA_PACK_PATTERN_RGB; + dma2_cfg |= mdp->dma_format; - dma2_cfg |= mdp->format; +#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 + if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) +#else + if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) +#endif + dma2_cfg |= DMA_PACK_PATTERN_BGR; + else + dma2_cfg |= DMA_PACK_PATTERN_RGB; - dma2_cfg |= DMA_OUT_SEL_LCDC; + dma2_cfg |= DMA_OUT_SEL_MDDI; - dma2_cfg |= DMA_IBUF_FORMAT_RGB565; - - } else { - dma2_cfg = DMA_PACK_TIGHT | - DMA_PACK_ALIGN_LSB | - DMA_OUT_SEL_AHB | - DMA_IBUF_NONCONTIGUOUS; + dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; - dma2_cfg |= mdp->format; - - #if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 - if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) - #else - if (mdp->format == DMA_IBUF_FORMAT_XRGB8888) - #endif - dma2_cfg |= DMA_PACK_PATTERN_BGR; - else - dma2_cfg |= DMA_PACK_PATTERN_RGB; - - dma2_cfg |= DMA_OUT_SEL_MDDI; - - dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; - - dma2_cfg |= DMA_DITHER_EN; - } + dma2_cfg |= DMA_DITHER_EN; if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) { dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; @@ -341,12 +420,12 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, DMA_IBUF_NONCONTIGUOUS; #endif - dma2_cfg |= mdp->format; + dma2_cfg |= mdp->dma_format; #if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30 - if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) + if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888) #else - if (mdp->format == DMA_IBUF_FORMAT_XRGB8888) + if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) #endif dma2_cfg |= DMA_PACK_PATTERN_BGR; else @@ -417,6 +496,7 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, mdp_writel(mdp, 0, MDP_DMA_P_START); #endif } +#endif /* ifndef CONFIG_MSM_MDP40 */ void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride, uint32_t width, uint32_t height, uint32_t x, uint32_t y, @@ -435,54 +515,21 @@ void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride, spin_lock_irqsave(&mdp->lock, flags); if (locked_enable_mdp_irq(mdp, out_if->dma_mask)) { + /* something wrong in dma, workaround it */ + mdp_dma_timer_enable = 1; pr_err("%s: busy\n", __func__); - goto done; } out_if->dma_cb = callback; out_if->dma_start(out_if->priv, addr, stride, width, height, x, y); -done: + + if (mdp_dma_timer_enable) + mod_timer(&mdp->dma_timer, + jiffies + msecs_to_jiffies(17)); + spin_unlock_irqrestore(&mdp->lock, flags); } -static int get_img(struct mdp_img *img, struct fb_info *info, - unsigned long *start, unsigned long *len, - struct file** filep) -{ - int put_needed, ret = 0; - struct file *file; - unsigned long vstart; - - if (!get_pmem_file(img->memory_id, start, &vstart, len, filep)) - return 0; - else if (!get_msm_hw3d_file(img->memory_id, &img->offset, start, len, - filep)) - return 0; - - file = fget_light(img->memory_id, &put_needed); - if (file == NULL) - return -1; - - if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { - *start = info->fix.smem_start; - *len = info->fix.smem_len; - ret = 0; - } else - ret = -1; - fput_light(file, put_needed); - - return ret; -} - -static void put_img(struct file *file) -{ - if (file) { - if (is_pmem_file(file)) - put_pmem_file(file); - else if (is_msm_hw3d_file(file)) - put_msm_hw3d_file(file); - } -} void mdp_configure_dma(struct mdp_device *mdp_dev) { @@ -494,7 +541,7 @@ void mdp_configure_dma(struct mdp_device *mdp_dev) dma_cfg = mdp_readl(mdp, MDP_DMA_P_CONFIG); dma_cfg &= ~DMA_IBUF_FORMAT_MASK; dma_cfg &= ~DMA_PACK_PATTERN_MASK; - dma_cfg |= (mdp->format | mdp->pack_pattern); + dma_cfg |= (mdp->dma_format | mdp->dma_pack_pattern); mdp_writel(mdp, dma_cfg, MDP_DMA_P_CONFIG); mdp->dma_config_dirty = false; @@ -514,6 +561,13 @@ int mdp_check_output_format(struct mdp_device *mdp_dev, int bpp) return 0; } +void mdp_set_panel_size(struct mdp_device *mdp_dev, int width, int height) +{ + struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); + mdp->mdp_dev.width = width; + mdp->mdp_dev.height = height; +} + int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp) { struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); @@ -542,214 +596,24 @@ int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp) default: return -EINVAL; } - if (format != mdp->format || pack_pattern != mdp->pack_pattern) { - mdp->format = format; - mdp->pack_pattern = pack_pattern; + if (format != mdp->dma_format || pack_pattern != mdp->dma_pack_pattern) { + mdp->dma_format = format; + mdp->dma_pack_pattern = pack_pattern; mdp->dma_config_dirty = true; } return 0; } -static void dump_req(struct mdp_blit_req *req, - unsigned long src_start, unsigned long src_len, - unsigned long dst_start, unsigned long dst_len) -{ - pr_err("flags: 0x%x\n", req->flags); - pr_err("src_start: 0x%08lx\n", src_start); - pr_err("src_len: 0x%08lx\n", src_len); - pr_err("src.offset: 0x%x\n", req->src.offset); - pr_err("src.format: 0x%x\n", req->src.format); - pr_err("src.width: %d\n", req->src.width); - pr_err("src.height: %d\n", req->src.height); - pr_err("src_rect.x: %d\n", req->src_rect.x); - pr_err("src_rect.y: %d\n", req->src_rect.y); - pr_err("src_rect.w: %d\n", req->src_rect.w); - pr_err("src_rect.h: %d\n", req->src_rect.h); - - pr_err("dst_start: 0x%08lx\n", dst_start); - pr_err("dst_len: 0x%08lx\n", dst_len); - pr_err("dst.offset: 0x%x\n", req->dst.offset); - pr_err("dst.format: 0x%x\n", req->dst.format); - pr_err("dst.width: %d\n", req->dst.width); - pr_err("dst.height: %d\n", req->dst.height); - pr_err("dst_rect.x: %d\n", req->dst_rect.x); - pr_err("dst_rect.y: %d\n", req->dst_rect.y); - pr_err("dst_rect.w: %d\n", req->dst_rect.w); - pr_err("dst_rect.h: %d\n", req->dst_rect.h); -} - -int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) -{ - int ret; - enable_mdp_irq(mdp, DL0_ROI_DONE); - ret = mdp_ppp_blit(mdp, req, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - if (unlikely(ret)) { - disable_mdp_irq(mdp, DL0_ROI_DONE); - return ret; - } - ret = mdp_ppp_wait(mdp); - if (unlikely(ret)) { - printk(KERN_ERR "%s: failed!\n", __func__); - pr_err("original request:\n"); - dump_req(mdp->req, src_start, src_len, dst_start, dst_len); - pr_err("dead request:\n"); - dump_req(req, src_start, src_len, dst_start, dst_len); - BUG(); - return ret; - } - return 0; -} - int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb, struct mdp_blit_req *req) { - int ret; - unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0; struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - struct file *src_file = 0, *dst_file = 0; - -#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302) - if (req->flags & MDP_ROT_90) { - if (unlikely(((req->dst_rect.h == 1) && - ((req->src_rect.w != 1) || - (req->dst_rect.w != req->src_rect.h))) || - ((req->dst_rect.w == 1) && ((req->src_rect.h != 1) || - (req->dst_rect.h != req->src_rect.w))))) { - pr_err("mpd_ppp: error scaling when size is 1!\n"); - return -EINVAL; - } - } else { - if (unlikely(((req->dst_rect.w == 1) && - ((req->src_rect.w != 1) || - (req->dst_rect.h != req->src_rect.h))) || - ((req->dst_rect.h == 1) && ((req->src_rect.h != 1) || - (req->dst_rect.h != req->src_rect.h))))) { - pr_err("mpd_ppp: error scaling when size is 1!\n"); - return -EINVAL; - } - } -#endif - - /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */ - if (unlikely(req->src_rect.h == 0 || - req->src_rect.w == 0)) { - printk(KERN_ERR "mdp_ppp: src img of zero size!\n"); - return -EINVAL; - } - if (unlikely(req->dst_rect.h == 0 || - req->dst_rect.w == 0)) - return -EINVAL; - - /* do this first so that if this fails, the caller can always - * safely call put_img */ - if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) { - printk(KERN_ERR "mdp_ppp: could not retrieve src image from " - "memory\n"); - return -EINVAL; - } - - if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) { - printk(KERN_ERR "mdp_ppp: could not retrieve dst image from " - "memory\n"); - put_img(src_file); - return -EINVAL; - } - mutex_lock(&mdp_mutex); - timeout_req = req; - /* transp_masking unimplemented */ - req->transp_mask = MDP_TRANSP_NOP; - mdp->req = req; -#if !defined(CONFIG_MSM_MDP31) && !defined(CONFIG_MSM_MDP302) - if (unlikely((req->transp_mask != MDP_TRANSP_NOP || - req->alpha != MDP_ALPHA_NOP || - HAS_ALPHA(req->src.format)) && - (req->flags & MDP_ROT_90 && - req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) { - int i; - unsigned int tiles = req->dst_rect.h / 16; - unsigned int remainder = req->dst_rect.h % 16; - req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h; - req->dst_rect.h = 16; - for (i = 0; i < tiles; i++) { - ret = mdp_blit_and_wait(mdp, req, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - if (ret) - goto end; - req->dst_rect.y += 16; - req->src_rect.x += req->src_rect.w; - } - if (!remainder) - goto end; - req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h; - req->dst_rect.h = remainder; - } -#else - /* Workarounds for MDP 3.1 hardware bugs */ - if (unlikely((mdp_get_bytes_per_pixel(req->dst.format) == 4) && - (req->dst_rect.w != 1) && - (((req->dst_rect.w % 8) == 6) || - ((req->dst_rect.w % 32) == 3) || - ((req->dst_rect.w % 32) == 1)))) { - ret = mdp_ppp_blit_split_width(mdp, req, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - goto end; - } else if (unlikely((req->dst_rect.w != 1) && (req->dst_rect.h != 1) && - ((req->dst_rect.h % 32) == 3 || - (req->dst_rect.h % 32) == 1))) { - ret = mdp_ppp_blit_split_height(mdp, req, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - goto end; - } -#endif - ret = mdp_blit_and_wait(mdp, req, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); -end: - put_img(src_file); - put_img(dst_file); - mutex_unlock(&mdp_mutex); - return ret; + return mdp_ppp_blit(mdp, fb, req); } -int mdp_fb_mirror(struct mdp_device *mdp_dev, - struct fb_info *src_fb, struct fb_info *dst_fb, - struct mdp_blit_req *req) -{ - int ret; - struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - if (!src_fb || !dst_fb) - return -EINVAL; - - enable_mdp_irq(mdp, DL0_ROI_DONE); - ret = mdp_ppp_blit(mdp, req, - -1, src_fb->fix.smem_start, src_fb->fix.smem_len, - -1, dst_fb->fix.smem_start, dst_fb->fix.smem_len); - if (ret) - goto err_bad_blit; - - ret = mdp_ppp_wait(mdp); - if (ret) { - pr_err("mdp_ppp_wait error\n"); - goto err_wait_failed; - } - return 0; - -err_bad_blit: - disable_mdp_irq(mdp, DL0_ROI_DONE); - -err_wait_failed: - return ret; -} void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id) { @@ -765,7 +629,7 @@ int mdp_out_if_register(struct mdp_device *mdp_dev, int interface, mdp_dma_start_func_t dma_start) { struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - unsigned long flags; + unsigned long flags=0; int ret = 0; if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) { @@ -798,7 +662,7 @@ int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface, uint32_t mask, struct msmfb_callback *cb) { struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - unsigned long flags; + unsigned long flags=0; int ret = 0; if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) { @@ -841,94 +705,6 @@ int register_mdp_client(struct class_interface *cint) return class_interface_register(cint); } -#ifdef CONFIG_MSM_MDP40 -void mdp_hw_init(struct mdp_info *mdp) -{ - mdp_irq_mask = 0; - mdp_writel(mdp, 0, MDP_INTR_ENABLE); -} -#else -#include "mdp_csc_table.h" - -void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata) -{ - mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0); - mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN); - mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0); - mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS); -} -void mdp_hw_init(struct mdp_info *mdp) -{ - int n; - int lcdc_enabled; - - mdp_irq_mask = 0; - - mdp_writel(mdp, 0, MDP_INTR_ENABLE); - - /* debug interface write access */ - mdp_writel(mdp, 1, 0x60); - mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); - -#ifndef CONFIG_MSM_MDP22 - lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN); - /* disable lcdc */ - mdp_writel(mdp, 0, MDP_LCDC_EN); - /* enable auto clock gating for all blocks by default */ - mdp_writel(mdp, 0xffffffff, MDP_CGC_EN); - /* reset color/gamma correct parms */ - mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG); -#endif - - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc); - mdp_writel(mdp, 1, 0x60); - - for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++) - mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg); - - /* clear up unused fg/main registers */ - /* comp.plane 2&3 ystride */ - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120); - - /* unpacked pattern */ - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c); - - /* comp.plane 2 & 3 */ - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118); - - /* clear unused bg registers */ - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0); - mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4); - - for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++) - mdp_writel(mdp, csc_matrix_config_table[n].val, - csc_matrix_config_table[n].reg); - - mdp_ppp_init_scale(mdp); - -#ifndef CONFIG_MSM_MDP31 - mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG); -#endif -#ifndef CONFIG_MSM_MDP22 - if(lcdc_enabled) - mdp_writel(mdp, 1, MDP_LCDC_EN); -#endif -} -#endif //CONFIG_MSM_MDP40 - int mdp_probe(struct platform_device *pdev) { struct resource *resource; @@ -974,9 +750,13 @@ int mdp_probe(struct platform_device *pdev) #endif mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp; mdp->mdp_dev.set_output_format = mdp_set_output_format; + mdp->mdp_dev.set_panel_size = mdp_set_panel_size; mdp->mdp_dev.check_output_format = mdp_check_output_format; mdp->mdp_dev.configure_dma = mdp_configure_dma; + mdp->enable_irq = enable_mdp_irq; + mdp->disable_irq = disable_mdp_irq; + if (pdata == NULL || pdata->overrides == 0) mdp->mdp_dev.overrides = 0; else if(pdata->overrides) @@ -987,27 +767,27 @@ int mdp_probe(struct platform_device *pdev) else if(pdata->color_format) mdp->mdp_dev.color_format = pdata->color_format; - if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) { #ifdef CONFIG_MSM_MDP40 - if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) { - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE - | MDP_DMA_S_DONE, mdp4_mddi_overlay); - } else { - ret = mdp_out_if_register(&mdp->mdp_dev, - MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE, - mdp4_mddi_overlay); - } + if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) { + ret = mdp_out_if_register(&mdp->mdp_dev, + MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE + | MDP_DMA_S_DONE, mdp4_mddi_overlay); + } else { + ret = mdp_out_if_register(&mdp->mdp_dev, + MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE, + mdp4_mddi_overlay); + } #else + if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) { ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE, mdp_dma_to_mddi); -#endif } else if (pdata->dma_channel == MDP_DMA_S) { ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_S_DONE, mdp_dmas_to_mddi); } +#endif if (ret) goto error_mddi_pmdh_register; @@ -1019,13 +799,12 @@ int mdp_probe(struct platform_device *pdev) goto error_get_mdp_clk; } - mdp->ebi1_clk = clk_get(NULL, "ebi1_clk"); - if (IS_ERR(mdp->ebi1_clk)) { - pr_err("mdp: failed to get ebi1 clk\n"); - ret = PTR_ERR(mdp->ebi1_clk); - goto error_get_ebi1_clk; - } - + mdp->ebi1_clk = clk_get(NULL, "ebi1_clk"); + if (IS_ERR(mdp->ebi1_clk)) { + pr_err("mdp: failed to get ebi1 clk\n"); + ret = PTR_ERR(mdp->ebi1_clk); + goto error_get_ebi1_clk; + } ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp); if (ret) @@ -1034,6 +813,7 @@ int mdp_probe(struct platform_device *pdev) clk_enable(mdp->clk); mdp_clk_to_disable_later = mdp->clk; + #ifdef CONFIG_MSM_MDP40 //MDP_DISP_INTF_SEL if (mdp_readl(mdp, 0xc0000)) @@ -1045,7 +825,6 @@ int mdp_probe(struct platform_device *pdev) #endif #ifdef CONFIG_MSM_MDP40 -extern void mdp4_hw_init(struct mdp_info *mdp); mdp4_hw_init(mdp); #else mdp_hw_init(mdp); @@ -1069,6 +848,10 @@ extern void mdp4_hw_init(struct mdp_info *mdp); if (ret) goto error_device_register; + setup_timer(&mdp->standby_timer, mdp_do_standby_timer, (unsigned long )mdp); + setup_timer(&mdp->dma_timer, mdp_do_dma_timer, (unsigned long )mdp); + + pr_info("%s: initialized\n", __func__); return 0; diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/msm/mdp_hw.h index c9784f2b..2f51ed40 100644 --- a/drivers/video/msm/mdp_hw.h +++ b/drivers/video/msm/mdp_hw.h @@ -47,12 +47,61 @@ struct mdp_info { char * __iomem base; int irq; struct clk *clk; + struct clk *pclk; struct clk *ebi1_clk; struct mdp_out_interface out_if[MSM_MDP_NUM_INTERFACES]; - int format; - int pack_pattern; + int dma_format; + int dma_pack_pattern; bool dma_config_dirty; struct mdp_blit_req *req; + uint32_t state; + struct timer_list standby_timer; + struct timer_list dma_timer; + + int (*enable_irq)(struct mdp_info *mdp, uint32_t mask); + int (*disable_irq)(struct mdp_info *mdp, uint32_t mask); +}; + +struct mdp_lcdc_info { + struct mdp_info *mdp; + struct clk *mdp_clk; + struct clk *mdp_pclk; + struct clk *pclk; + struct clk *pad_pclk; + struct msm_panel_data fb_panel_data; + struct platform_device fb_pdev; + struct msm_lcdc_platform_data *pdata; + uint32_t fb_start; + + struct msmfb_callback frame_start_cb; + wait_queue_head_t vsync_waitq; + int got_vsync; + unsigned color_format; + struct { + uint32_t clk_rate; + uint32_t hsync_ctl; + uint32_t vsync_period; + uint32_t vsync_pulse_width; + uint32_t display_hctl; + uint32_t display_vstart; + uint32_t display_vend; + uint32_t hsync_skew; + uint32_t polarity; + } parms; + atomic_t blank_count; + struct mutex blank_lock; +}; + +struct panel_icm_info { + bool icm_mode; + bool icm_doable; + bool clock_enabled; + int panel_update; + bool icm_suspend; + struct mutex icm_lock; + struct mdp_lcdc_info *lcdc; + spinlock_t lock; + void (*force_leave)(void); }; extern int mdp_out_if_register(struct mdp_device *mdp_dev, int interface, @@ -64,15 +113,21 @@ extern int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface, struct mdp_blit_req; struct mdp_device; -int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, - unsigned long src_len, struct file *dst_file, - unsigned long dst_start, unsigned long dst_len); void mdp_ppp_dump_debug(const struct mdp_info *mdp); +int mdp_hw_init(struct mdp_info *mdp); +void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata); +void mdp_dump_blit(struct mdp_blit_req *req); +int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq); #define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset) #define mdp_readl(mdp, offset) readl(mdp->base + offset) +#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data) +#define panel_to_dtv(p) container_of((p), struct mdp_dtv_info, fb_panel_data) + +/* define mdp state for multi purpose */ +#define MDP_STATE_STANDBY (1 << 0) + #ifdef CONFIG_MSM_MDP302 #define MDP_SYNC_CONFIG_0 ( 0x00300) @@ -142,6 +197,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define MDP_VSYNC_CTRL (0x0008c) #define MDP_MDDI_PARAM_WR_SEL (0x00090) #define MDP_MDDI_PARAM (0x00094) +#define MDP_MDDI_DATA_XFR (0x00098) #define MDP_CGC_EN (0x00100) #define MDP_CMD_STATUS (0x10008) #define MDP_PROFILE_EN (0x10010) @@ -292,6 +348,21 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define MDP_LCDC_HSYNC_SKEW (0xc0030) #define MDP_LCDC_TEST_CTL (0xc0034) #define MDP_LCDC_CTL_POLARITY (0xc0038) + +#define MDP_DTV_EN (0xd0000) +#define MDP_DTV_HSYNC_CTL (0xd0004) +#define MDP_DTV_VSYNC_PERIOD (0xd0008) +#define MDP_DTV_VSYNC_PULSE_WIDTH (0xd000c) +#define MDP_DTV_DISPLAY_HCTL (0xd0018) +#define MDP_DTV_DISPLAY_V_START (0xd001c) +#define MDP_DTV_DISPLAY_V_END (0xd0020) +#define MDP_DTV_ACTIVE_HCTL (0xd002c) +#define MDP_DTV_ACTIVE_V_START (0xd0030) +#define MDP_DTV_ACTIVE_V_END (0xd0038) +#define MDP_DTV_BORDER_CLR (0xd0040) +#define MDP_DTV_UNDERFLOW_CTL (0xd0044) +#define MDP_DTV_HSYNC_SKEW (0xd0048) +#define MDP_DTV_CTL_POLARITY (0xd0050) #else #define MDP_LCDC_EN (0xe0000) #define MDP_LCDC_HSYNC_CTL (0xe0004) @@ -321,6 +392,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define TV_OUT_DMA3_DONE (1<<6) #define TV_ENC_UNDERRUN (1<<7) #define TV_OUT_FRAME_START (1<<13) +#define MDP_HIST_DONE (1<<20) #ifdef CONFIG_MSM_MDP22 #define MDP_DMA_P_DONE (1 << 2) @@ -800,6 +872,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define DMA_PACK_LOOSE 0 #define DMA_PACK_ALIGN_LSB 0 #define DMA_PACK_ALIGN_MSB (1<<7) +#define DMA_PACK_ALIGN_MASK (1<<7) #define DMA_PACK_PATTERN_MASK (0x3f<<8) #define DMA_PACK_PATTERN_RGB \ (MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8) @@ -823,31 +896,14 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); #define DMA_IBUF_FORMAT_MASK (1 << 20) #define DMA_IBUF_NONCONTIGUOUS (1<<21) -#elif defined(CONFIG_MSM_MDP30) - -#define DMA_OUT_SEL_AHB 0 -#define DMA_OUT_SEL_MDDI (1<<19) -#define DMA_AHBM_LCD_SEL_PRIMARY 0 -#define DMA_AHBM_LCD_SEL_SECONDARY (0) -#define DMA_IBUF_C3ALPHA_EN (0) -#define DMA_DITHER_EN (1<<24) - -#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0 -#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (0) -#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (0) - -#define DMA_IBUF_FORMAT_MASK (1 << 20) -#define DMA_IBUF_FORMAT_RGB565 (1<<25) -#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 (1<<26) -#define DMA_IBUF_NONCONTIGUOUS (0) - -#else /* CONFIG_MSM_MDP31 | CONFIG_MSM_MDP302 */ +#else /* CONFIG_MSM_MDP31 || CONFIG_MSM_MDP40 */ #define DMA_OUT_SEL_AHB (0 << 19) #define DMA_OUT_SEL_MDDI (1 << 19) #define DMA_OUT_SEL_LCDC (2 << 19) #define DMA_OUT_SEL_LCDC_MDDI (3 << 19) #define DMA_DITHER_EN (1 << 24) +#define DMA_DEFLKR_EN (1 << 24) /* dma_e */ #define DMA_IBUF_FORMAT_RGB888 (0 << 25) #define DMA_IBUF_FORMAT_RGB565 (1 << 25) #define DMA_IBUF_FORMAT_XRGB8888 (2 << 25) @@ -862,6 +918,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp); /* MDDI REGISTER ? */ #define MDDI_VDO_PACKET_DESC_RGB565 0x5565 #define MDDI_VDO_PACKET_DESC_RGB666 0x5666 +#define MDDI_VDO_PACKET_DESC_RGB888 0x5888 #define MDDI_VDO_PACKET_PRIM 0xC3 #define MDDI_VDO_PACKET_SECD 0xC0 diff --git a/drivers/video/msm/mdp_hw_legacy.c b/drivers/video/msm/mdp_hw_legacy.c new file mode 100644 index 00000000..20970643 --- /dev/null +++ b/drivers/video/msm/mdp_hw_legacy.c @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2010 Google, Inc. + * Author: Dima Zavin + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include + +#include "mdp_hw.h" +#include "mdp_ppp.h" +#include "mdp_csc_table.h" + +#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000) +static unsigned int mdp_irq_mask; +#if 0 +static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride, + uint32_t width, uint32_t height, uint32_t x, + uint32_t y) +{ + struct mdp_info *mdp = priv; + uint32_t dma2_cfg; + uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */ + + dma2_cfg = DMA_PACK_TIGHT | + DMA_PACK_ALIGN_LSB | + DMA_OUT_SEL_AHB | + DMA_IBUF_NONCONTIGUOUS; + + dma2_cfg |= mdp->dma_format; + dma2_cfg |= mdp->dma_pack_pattern; + + dma2_cfg |= DMA_OUT_SEL_MDDI; + + dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY; + + dma2_cfg |= DMA_DITHER_EN; + + /* 666 18BPP */ + dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; + +#ifdef CONFIG_MSM_MDP22 + /* setup size, address, and stride */ + mdp_writel(mdp, (height << 16) | (width), + MDP_CMD_DEBUG_ACCESS_BASE + 0x0184); + mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188); + mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C); + + /* set y & x offset and MDDI transaction parameters */ + mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194); + mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0); + if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM, + MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); + else + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM, + MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4); + mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180); + + /* start DMA2 */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044); +#else + /* setup size, address, and stride */ + mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE); + mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR); + mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE); + + /* set y & x offset and MDDI transaction parameters */ + mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY); + mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL); + if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM, + MDP_MDDI_PARAM); + else + mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM, + MDP_MDDI_PARAM); + + mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR); + mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG); + mdp_writel(mdp, 0, MDP_DMA_P_START); +#endif +} +#endif +#if defined CONFIG_MSM_MDP302 +void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata) +{ mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0); + mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN); + mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0); + mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS); +} +#endif +#if 0 +int mdp_hw_init(struct mdp_info *mdp) +{ + int n; + + n = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp, + MDP_DMA_P_DONE, mdp_dma_to_mddi); + if (n) + return n; + + mdp_writel(mdp, 0, MDP_INTR_ENABLE); + + /* debug interface write access */ + mdp_writel(mdp, 1, 0x60); + mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); + +#ifndef CONFIG_MSM_MDP22 + /* disable lcdc */ + mdp_writel(mdp, 0, MDP_LCDC_EN); + /* enable auto clock gating for all blocks by default */ + mdp_writel(mdp, 0xffffffff, MDP_CGC_EN); + /* reset color/gamma correct parms */ + mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG); +#endif + + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc); + mdp_writel(mdp, 1, 0x60); + + for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++) + mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg); + + /* clear up unused fg/main registers */ + /* comp.plane 2&3 ystride */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120); + + /* unpacked pattern */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c); + + /* comp.plane 2 & 3 */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118); + + /* clear unused bg registers */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4); + + for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++) + mdp_writel(mdp, csc_matrix_config_table[n].val, + csc_matrix_config_table[n].reg); + + mdp_ppp_init_scale(mdp); + +#ifndef CONFIG_MSM_MDP31 + mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG); +#endif + + return 0; +} +#endif + +int mdp_hw_init(struct mdp_info *mdp) +{ + int n; + int lcdc_enabled; + + mdp_irq_mask = 0; + + mdp_writel(mdp, 0, MDP_INTR_ENABLE); + + /* debug interface write access */ + mdp_writel(mdp, 1, 0x60); + mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE); + +#ifndef CONFIG_MSM_MDP22 + lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN); + /* disable lcdc */ + mdp_writel(mdp, 0, MDP_LCDC_EN); + /* enable auto clock gating for all blocks by default */ + mdp_writel(mdp, 0xffffffff, MDP_CGC_EN); + /* reset color/gamma correct parms */ + mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG); +#endif + + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc); + mdp_writel(mdp, 1, 0x60); + + for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++) + mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg); + + /* clear up unused fg/main registers */ + /* comp.plane 2&3 ystride */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120); + + /* unpacked pattern */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c); + + /* comp.plane 2 & 3 */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118); + + /* clear unused bg registers */ + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0); + mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4); + + for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++) + mdp_writel(mdp, csc_matrix_config_table[n].val, + csc_matrix_config_table[n].reg); + + mdp_ppp_init_scale(mdp); + +#ifndef CONFIG_MSM_MDP31 + mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG); +#endif +#ifndef CONFIG_MSM_MDP22 + if (lcdc_enabled) + mdp_writel(mdp, 1, MDP_LCDC_EN); +#endif + return 0; +} diff --git a/drivers/video/msm/mdp_lcdc.c b/drivers/video/msm/mdp_lcdc.c index bb2a9698..def3a7d3 100644 --- a/drivers/video/msm/mdp_lcdc.c +++ b/drivers/video/msm/mdp_lcdc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,9 @@ #ifdef CONFIG_MSM_MDP40 #include "mdp4.h" #endif +#ifdef CONFIG_PANEL_SELF_REFRESH +#include +#endif #if 0 #define D(fmt, args...) printk(KERN_INFO "Dispaly: " fmt, ##args) @@ -43,32 +47,6 @@ #if defined(CONFIG_ARCH_MSM7227) #define LCDC_MUX_CTL (MSM_TGPIO1_BASE + 0x278) #endif -struct mdp_lcdc_info { - struct mdp_info *mdp; - struct clk *mdp_clk; - struct clk *pclk; - struct clk *pad_pclk; - struct msm_panel_data fb_panel_data; - struct platform_device fb_pdev; - struct msm_lcdc_platform_data *pdata; - uint32_t fb_start; - - struct msmfb_callback frame_start_cb; - wait_queue_head_t vsync_waitq; - int got_vsync; - unsigned color_format; - struct { - uint32_t clk_rate; - uint32_t hsync_ctl; - uint32_t vsync_period; - uint32_t vsync_pulse_width; - uint32_t display_hctl; - uint32_t display_vstart; - uint32_t display_vend; - uint32_t hsync_skew; - uint32_t polarity; - } parms; -}; static struct mdp_device *mdp_dev; @@ -76,7 +54,142 @@ static struct mdp_device *mdp_dev; static struct mdp4_overlay_pipe *lcdc_pipe; #endif -#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data) +#ifdef CONFIG_PANEL_SELF_REFRESH +#if 0 +#define ICM_DBG(s...) printk("[icm]" s) +#else +#define ICM_DBG(s...) do {} while (0) +#endif + +/* set the timeout to 200 milliseconds */ +#define PANEL_ENTER_IDLE_TIMEOUT HZ/5 +/* Afetr setting ICM=1, we need to keep sending the RGB signal more than 2-frame */ +#define PANEL_IDLE_STABLE_TIMEOUT 48 + +static struct task_struct *th_display; +struct panel_icm_info *panel_icm; +DECLARE_WAIT_QUEUE_HEAD(panel_update_wait_queue); +#endif + +#ifdef CONFIG_PANEL_SELF_REFRESH +static int icm_check_panel_update(void) +{ + int ret; + unsigned long irq_flags = 0; + + spin_lock_irqsave(&panel_icm->lock, irq_flags); + ret = panel_icm->panel_update; + spin_unlock_irqrestore(&panel_icm->lock, irq_flags); + return ret; +} + +static int icm_thread(void *data) +{ + struct mdp_lcdc_info *lcdc; + struct msm_lcdc_panel_ops *panel_ops; + int rc; + unsigned long irq_flags = 0; + + lcdc = data; + panel_ops = lcdc->pdata->panel_ops; + while (1) { + rc = wait_event_timeout(panel_update_wait_queue, icm_check_panel_update() == 1, PANEL_ENTER_IDLE_TIMEOUT); + ICM_DBG("ICM Thread:wake up rc=%d \n", rc); + mutex_lock(&panel_icm->icm_lock); + if (rc == 0 && icm_check_panel_update() != 1) {/* wait_timeout */ + ICM_DBG("EnterICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); + if (panel_icm->icm_mode == false && panel_icm->icm_doable == true) { + + if (panel_ops->refresh_enable) + panel_ops->refresh_enable(panel_ops); + + panel_icm->icm_mode = true; + msleep(PANEL_IDLE_STABLE_TIMEOUT); + + mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); + clk_disable(lcdc->pad_pclk); + clk_disable(lcdc->pclk); + clk_disable(lcdc->mdp_clk); + panel_icm->clock_enabled = false; + pr_info("EnterICM: enter ICM MODE done!!!\n"); + } + } else {/* get update event, no timeout */ + ICM_DBG("Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); + if (panel_icm->icm_mode == true && panel_icm->icm_doable == true) { + clk_enable(lcdc->mdp_clk); + clk_enable(lcdc->pclk); + clk_enable(lcdc->pad_pclk); + mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); + panel_icm->clock_enabled = true; + + if (panel_ops->refresh_disable) + panel_ops->refresh_disable(panel_ops); + + panel_icm->icm_mode = false; + pr_info("LeaveICM: leave ICM MODE done !!!\n"); + } + spin_lock_irqsave(&panel_icm->lock, irq_flags); + panel_icm->panel_update = 0; + spin_unlock_irqrestore(&panel_icm->lock, irq_flags); + } + mutex_unlock(&panel_icm->icm_lock); + } /* end while */ + return 0; +} + +static void icm_force_leave(void) +{ + struct msm_lcdc_panel_ops *panel_ops; + unsigned long irq_flags = 0; + + panel_ops = panel_icm->lcdc->pdata->panel_ops; + + mutex_lock(&panel_icm->icm_lock); + ICM_DBG("Force Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable); + if (panel_icm->icm_mode == true) { + clk_enable(panel_icm->lcdc->mdp_clk); + clk_enable(panel_icm->lcdc->pclk); + clk_enable(panel_icm->lcdc->pad_pclk); + mdp_writel(panel_icm->lcdc->mdp, 1, MDP_LCDC_EN); + panel_icm->clock_enabled = true; + if (panel_ops->refresh_disable) + panel_ops->refresh_disable(panel_ops); + panel_icm->icm_mode = false; + panel_icm->icm_doable = true; + pr_info("ForceLeaveICM: leave ICM MODE done !!!\n"); + } + spin_lock_irqsave(&panel_icm->lock, irq_flags); + panel_icm->panel_update = 0; + spin_unlock_irqrestore(&panel_icm->lock, irq_flags); + mutex_unlock(&panel_icm->icm_lock); +} + +static int icm_init(struct mdp_lcdc_info *lcdc) +{ + int ret = 0; + + /* init panel_icm_info */ + panel_icm = kzalloc(sizeof(struct panel_icm_info), GFP_KERNEL); + if (!panel_icm) + return -ENOMEM; + panel_icm->icm_doable = 1; + panel_icm->clock_enabled = true; + panel_icm->lcdc = lcdc; + panel_icm->force_leave = icm_force_leave; + panel_icm->icm_suspend = false; + mutex_init(&panel_icm->icm_lock); + th_display = kthread_run(icm_thread, lcdc, "panel-enterIdle"); + if (IS_ERR(th_display)) { + ret = PTR_ERR(th_display); + pr_err("%s: panel_icm_thread create fail:%d!!!\n", __func__, ret); + goto error_create_thread; + } + return ret; +error_create_thread: + kfree(panel_icm); + return ret; +} +#endif static int lcdc_unblank(struct msm_panel_data *fb_panel) { @@ -85,7 +198,8 @@ static int lcdc_unblank(struct msm_panel_data *fb_panel) pr_info("%s: ()\n", __func__); - panel_ops->unblank(panel_ops); + if (panel_ops->unblank) + panel_ops->unblank(panel_ops); return 0; } @@ -96,14 +210,28 @@ static int lcdc_blank(struct msm_panel_data *fb_panel) struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; pr_info("%s: ()\n", __func__); - panel_ops->blank(panel_ops); + + if (panel_ops->blank) + panel_ops->blank(panel_ops); return 0; } +static int lcdc_shutdown(struct msm_panel_data *fb_panel) +{ + struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); + struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; + + pr_info("%s: ()\n", __func__); + + if (panel_ops->shutdown) + panel_ops->shutdown(panel_ops); + + return 0; +} + static int lcdc_suspend(struct msm_panel_data *fb_panel) { - int status; struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; @@ -111,13 +239,39 @@ static int lcdc_suspend(struct msm_panel_data *fb_panel) #if defined(CONFIG_ARCH_MSM7227) writel(0x0, LCDC_MUX_CTL); - status = readl(LCDC_MUX_CTL); - D("suspend_lcdc_mux_ctl = %x\n", status); + D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL)); #endif +#ifdef CONFIG_PANEL_SELF_REFRESH + if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { + mutex_lock(&panel_icm->icm_lock); + panel_icm->icm_doable = false; + pr_info("[ICM %s]: icm mode=%d, clock_enabled=%d\n", __func__, panel_icm->icm_mode, panel_icm->clock_enabled); + if (panel_icm->icm_mode == true && panel_icm->clock_enabled == false) { + if (panel_ops->refresh_disable) + panel_ops->refresh_disable(panel_ops); + panel_icm->icm_mode = false; + } else { + mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); + clk_disable(lcdc->pad_pclk); + clk_disable(lcdc->pclk); + clk_disable(lcdc->mdp_clk); + } + panel_icm->clock_enabled = false; + mutex_unlock(&panel_icm->icm_lock); + } else { + mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); + clk_disable(lcdc->pad_pclk); + clk_disable(lcdc->pclk); + clk_disable(lcdc->mdp_clk); + } +#else mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN); clk_disable(lcdc->pad_pclk); clk_disable(lcdc->pclk); + if (lcdc->mdp_pclk) + clk_disable(lcdc->mdp_pclk); clk_disable(lcdc->mdp_clk); +#endif if (panel_ops->uninit) panel_ops->uninit(panel_ops); @@ -126,7 +280,6 @@ static int lcdc_suspend(struct msm_panel_data *fb_panel) static int lcdc_resume(struct msm_panel_data *fb_panel) { - unsigned int status; struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel); struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops; @@ -136,17 +289,26 @@ static int lcdc_resume(struct msm_panel_data *fb_panel) if (panel_ops->init(panel_ops) < 0) printk(KERN_ERR "LCD init fail!\n"); } - clk_enable(lcdc->mdp_clk); + if (lcdc->mdp_pclk) + clk_enable(lcdc->mdp_pclk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); #if defined(CONFIG_ARCH_MSM7227) writel(0x1, LCDC_MUX_CTL); - status = readl(LCDC_MUX_CTL); - D("resume_lcdc_mux_ctl = %x\n",status); + D("resume_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL)); #endif mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); +#ifdef CONFIG_PANEL_SELF_REFRESH + if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { + mutex_lock(&panel_icm->icm_lock); + panel_icm->icm_doable = true; + panel_icm->clock_enabled = true; + panel_icm->icm_suspend = false; + mutex_unlock(&panel_icm->icm_lock); + } +#endif return 0; } @@ -157,12 +319,13 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) uint32_t dma_cfg; clk_enable(lcdc->mdp_clk); + if (lcdc->mdp_pclk) + clk_enable(lcdc->mdp_pclk); clk_enable(lcdc->pclk); clk_enable(lcdc->pad_pclk); clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate); clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate); - /* write the lcdc params */ mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL); mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD); @@ -175,46 +338,45 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc) mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW); mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR); - mdp_writel(lcdc->mdp, 0xff, MDP_LCDC_UNDERFLOW_CTL); + mdp_writel(lcdc->mdp, 0x80000000 | 0xff, MDP_LCDC_UNDERFLOW_CTL); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START); mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END); mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY); - /* config the dma_p block that drives the lcdc data */ mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR); mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) | (fb_panel->fb_data->xres & 0x7ff)), MDP_DMA_P_SIZE); - mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY); dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG); -#if defined(CONFIG_MACH_HTCLEO) + dma_cfg &= ~(DMA_PACK_PATTERN_MASK | DMA_PACK_ALIGN_MASK); dma_cfg |= (DMA_PACK_ALIGN_MSB | - DMA_PACK_PATTERN_RGB | - DMA_DITHER_EN); + DMA_PACK_PATTERN_RGB | + DMA_DITHER_EN); dma_cfg |= DMA_OUT_SEL_LCDC; - dma_cfg |= DMA_IBUF_FORMAT_RGB565; - //dma_cfg &= ~DMA_DITHER_EN; // solve color banding issue - marc1706 + //zeusk: dma_cfg |= DMA_IBUF_FORMAT_RGB565; dma_cfg &= ~DMA_DST_BITS_MASK; -#else - dma_cfg |= (DMA_PACK_ALIGN_LSB | - DMA_PACK_PATTERN_RGB | - DMA_DITHER_EN); - dma_cfg |= DMA_OUT_SEL_LCDC; - dma_cfg &= ~DMA_DST_BITS_MASK; -#endif - if(lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB565) - dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS; - else if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB666) - dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS; + if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666) + dma_cfg |= DMA_DSTC0G_6BITS | + DMA_DSTC1B_6BITS | + DMA_DSTC2R_6BITS; + else if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB888) + dma_cfg |= DMA_DSTC0G_8BITS | + DMA_DSTC1B_8BITS | + DMA_DSTC2R_8BITS; + else + dma_cfg |= DMA_DSTC0G_6BITS | + DMA_DSTC1B_5BITS | + DMA_DSTC2R_5BITS; mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG); /* enable the lcdc timing generation */ mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN); + return 0; } @@ -301,35 +463,6 @@ static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride, mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR); } -#ifdef CONFIG_MSM_MDP40 -static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride, - uint32_t width, uint32_t height, uint32_t x, - uint32_t y) -{ - struct mdp_lcdc_info *lcdc = priv; - struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev); - - struct mdp4_overlay_pipe *pipe; - pipe = lcdc_pipe; - pipe->srcp0_addr = addr; - - if (mdp->dma_config_dirty) - { - if(mdp->format == DMA_IBUF_FORMAT_RGB565) { - pipe->src_format = MDP_RGB_565; - pipe->srcp0_ystride = pipe->src_width * 2; - } else if(mdp->format == DMA_IBUF_FORMAT_XRGB8888) { - pipe->src_format = MDP_RGBA_8888; - pipe->srcp0_ystride = pipe->src_width * 4; - } - mdp4_overlay_format2pipe(pipe); - mdp->dma_config_dirty = false; - } - mdp4_overlay_rgb_setup(pipe); - mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */ - -} -#endif static void precompute_timing_parms(struct mdp_lcdc_info *lcdc) { struct msm_lcdc_timing *timing = lcdc->pdata->timing; @@ -404,6 +537,10 @@ static int mdp_lcdc_probe(struct platform_device *pdev) goto err_get_mdp_clk; } + lcdc->mdp_pclk = clk_get(mdp_dev->dev.parent, "mdp_pclk"); + if (IS_ERR(lcdc->mdp_pclk)) + lcdc->mdp_pclk = NULL; + lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk"); if (IS_ERR(lcdc->pclk)) { pr_err("%s: failed to get lcdc_pclk\n", __func__); @@ -443,7 +580,10 @@ static int mdp_lcdc_probe(struct platform_device *pdev) if (lcdc_pipe == NULL) { ptype = mdp4_overlay_format2type(MDP_RGB_565); pipe = mdp4_overlay_pipe_alloc(ptype); + if (!pipe) + goto err_mdp4_overlay_pipe_alloc; pipe->mixer_stage = MDP4_MIXER_STAGE_BASE; + pipe->pipe_used = 1; pipe->mixer_num = MDP4_MIXER0; pipe->src_format = MDP_RGB_565; mdp4_overlay_format2pipe(pipe); @@ -463,15 +603,8 @@ static int mdp_lcdc_probe(struct platform_device *pdev) pipe->srcp0_addr = (uint32_t) lcdc->fb_start; pipe->srcp0_ystride = pdata->fb_data->xres * 2; - mdp4_overlay_dmap_xy(pipe); - mdp4_overlay_dmap_cfg(pipe, 1); - mdp4_overlay_rgb_setup(pipe); - mdp4_mixer_stage_up(pipe); - - mdp4_overlayproc_cfg(pipe); - mdp4_overlay_reg_flush(pipe, 1); #endif lcdc->fb_panel_data.suspend = lcdc_suspend; @@ -483,13 +616,12 @@ static int mdp_lcdc_probe(struct platform_device *pdev) lcdc->fb_panel_data.unblank = lcdc_unblank; lcdc->fb_panel_data.fb_data = pdata->fb_data; lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE; - + lcdc->fb_panel_data.shutdown = lcdc_shutdown; ret = lcdc_hw_init(lcdc); if (ret) { pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__); goto err_hw_init; } - lcdc->fb_pdev.name = "msm_panel"; lcdc->fb_pdev.id = pdata->fb_id; lcdc->fb_pdev.resource = pdata->fb_resource; @@ -504,16 +636,30 @@ static int mdp_lcdc_probe(struct platform_device *pdev) } pr_info("%s: initialized\n", __func__); +#ifdef CONFIG_PANEL_SELF_REFRESH + if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { + ret = icm_init(lcdc); + if (ret) { + pr_err("%s: Cannot init dispaly selfrefresh \n", __func__); + goto err_plat_dev_reg; + } + } +#endif return 0; err_plat_dev_reg: err_hw_init: +#ifdef CONFIG_MSM_MDP40 +err_mdp4_overlay_pipe_alloc: +#endif platform_set_drvdata(pdev, NULL); clk_put(lcdc->pad_pclk); err_get_pad_pclk: clk_put(lcdc->pclk); err_get_pclk: + if (lcdc->mdp_pclk) + clk_put(lcdc->mdp_pclk); clk_put(lcdc->mdp_clk); err_get_mdp_clk: kfree(lcdc); diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c index 334e2ebb..dd778035 100644 --- a/drivers/video/msm/mdp_ppp.c +++ b/drivers/video/msm/mdp_ppp.c @@ -15,8 +15,12 @@ #include #include #include +#include +#include #include +#include #include +#include #include #include "mdp_hw.h" @@ -52,19 +56,19 @@ static uint32_t dst_img_cfg[] = { PPP_ARRAY1(CFG, DST) }; -static uint32_t bytes_per_pixel[] = { +static const uint32_t bytes_per_pixel[] = { [MDP_RGB_565] = 2, - [MDP_RGB_888] = 3, [MDP_XRGB_8888] = 4, + [MDP_Y_CBCR_H2V2] = 1, [MDP_ARGB_8888] = 4, + [MDP_RGB_888] = 3, + [MDP_Y_CRCB_H2V2] = 1, + [MDP_YCRYCB_H2V1] = 2, + [MDP_Y_CRCB_H2V1] = 1, + [MDP_Y_CBCR_H2V1] = 1, [MDP_RGBA_8888] = 4, [MDP_BGRA_8888] = 4, [MDP_RGBX_8888] = 4, - [MDP_Y_CBCR_H2V1] = 1, - [MDP_Y_CBCR_H2V2] = 1, - [MDP_Y_CRCB_H2V1] = 1, - [MDP_Y_CRCB_H2V2] = 1, - [MDP_YCRYCB_H2V1] = 2 }; static uint32_t dst_op_chroma[] = { @@ -79,6 +83,9 @@ static uint32_t bg_op_chroma[] = { PPP_ARRAY1(CHROMA_SAMP, BG) }; +static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue); +DEFINE_MUTEX(mdp_mutex); + static uint32_t get_luma_offset(struct mdp_img *img, struct mdp_rect *rect, uint32_t bpp) { @@ -268,7 +275,6 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs) req->alpha &= 0xff; /* ALPHA BLEND */ if (HAS_ALPHA(req->src.format)) { -#if !defined(CONFIG_MACH_HTCLEO) regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON; if (req->flags & MDP_BLEND_FG_PREMULT) { #ifdef CONFIG_MSM_MDP31 @@ -285,10 +291,6 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs) } else { regs->op |= PPP_OP_BLEND_SRCPIXEL_ALPHA; } -#else - regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON; - regs->op |= PPP_OP_BLEND_SRCPIXEL_ALPHA; -#endif } else if (req->alpha < MDP_ALPHA_NOP) { /* just blend by alpha */ regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON | @@ -309,7 +311,7 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs) set_blend_region(&req->dst, &req->dst_rect, regs); } -static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req, +static int blit_scale(struct mdp_info *mdp, struct mdp_blit_req *req, struct ppp_regs *regs) { struct mdp_rect dst_rect; @@ -330,7 +332,7 @@ static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req, } if (mdp_ppp_cfg_scale(mdp, regs, &req->src_rect, &dst_rect, - req->src.format, req->dst.format)) { + req->src.format, req->dst.format)) { DLOG("crap, bad scale\n"); return -1; } @@ -339,7 +341,7 @@ static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req, return 0; } -static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req, +static void blit_blur(struct mdp_info *mdp, struct mdp_blit_req *req, struct ppp_regs *regs) { int ret; @@ -411,21 +413,23 @@ static void flush_imgs(struct mdp_blit_req *req, struct ppp_regs *regs, #ifdef CONFIG_ANDROID_PMEM uint32_t src0_len, src1_len, dst0_len, dst1_len; - /* flush src images to memory before dma to mdp */ - get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len, - &src1_len); - flush_pmem_file(src_file, req->src.offset, src0_len); - if (IS_PSEUDOPLNR(req->src.format)) - flush_pmem_file(src_file, req->src.offset + src0_len, - src1_len); + if (!(req->flags & MDP_BLIT_NON_CACHED)) { + /* flush src images to memory before dma to mdp */ + get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len, + &src1_len); + flush_pmem_file(src_file, req->src.offset, src0_len); + if (IS_PSEUDOPLNR(req->src.format)) + flush_pmem_file(src_file, req->src.offset + src0_len, + src1_len); - /* flush dst images */ - get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len, - &dst1_len); - flush_pmem_file(dst_file, req->dst.offset, dst0_len); - if (IS_PSEUDOPLNR(req->dst.format)) - flush_pmem_file(dst_file, req->dst.offset + dst0_len, - dst1_len); + /* flush dst images */ + get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len, + &dst1_len); + flush_pmem_file(dst_file, req->dst.offset, dst0_len); + if (IS_PSEUDOPLNR(req->dst.format)) + flush_pmem_file(dst_file, req->dst.offset + dst0_len, + dst1_len); + } #endif } @@ -439,6 +443,13 @@ static uint32_t get_chroma_base(struct mdp_img *img, uint32_t base, return addr; } +int mdp_get_bytes_per_pixel(int format) +{ + if (format < 0 || format >= MDP_IMGTYPE_LIMIT) + return -1; + return bytes_per_pixel[format]; +} + #if PPP_DUMP_BLITS #define mdp_writel_dbg(mdp, val, reg) do { \ pr_info("%s: writing 0x%08x=0x%08x\n", __func__, (reg), (val));\ @@ -501,19 +512,17 @@ static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, mdp_writel_dbg(mdp, regs->bg_img_sz, MDP_PPP_BG_IMAGE_SIZE); mdp_writel_dbg(mdp, regs->bg_alpha_sel, MDP_PPP_BLEND_BG_ALPHA_SEL); - -#if defined(CONFIG_MACH_HTCLEO) +#if 0 /* zeusk: defined(CONFIG_MACH_HTCLEO) */ mdp_writel_dbg(mdp, 0, MDP_TFETCH_TEST_MODE); #endif #endif } - if( src_file != -1 && dst_file != -1 ) - flush_imgs(req, regs, src_file, dst_file); + flush_imgs(req, regs, src_file, dst_file); mdp_writel_dbg(mdp, 0x1000, MDP_DISPLAY0_START); return 0; } - -void mdp_dump_blit(struct mdp_blit_req *req) +/* +static void mdp_dump_blit(struct mdp_blit_req *req) { pr_info("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__, req->src.width, req->src.height, req->src.format, @@ -531,8 +540,8 @@ void mdp_dump_blit(struct mdp_blit_req *req) pr_info("%s: transp_max=0x%08x\n", __func__, req->transp_mask); pr_info("%s: flags=%08x\n", __func__, req->flags); } - -int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, +*/ +static int process_blit(struct mdp_info *mdp, struct mdp_blit_req *req, struct file *src_file, unsigned long src_start, unsigned long src_len, struct file *dst_file, unsigned long dst_start, unsigned long dst_len) { @@ -644,13 +653,6 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req, return 0; } -int mdp_get_bytes_per_pixel(int format) -{ - if (format < 0 || format >= MDP_IMGTYPE_LIMIT) - return -1; - return bytes_per_pixel[format]; -} - #define mdp_dump_register(mdp, reg) \ printk(# reg ": %08x\n", mdp_readl((mdp), (reg))) @@ -668,234 +670,164 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp) mdp_dump_register(mdp, MDP_INTR_ENABLE); } - -/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */ -int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +static int mdp_ppp_wait(struct mdp_info *mdp) { int ret; - struct mdp_blit_req splitreq; - int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; - int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; - splitreq = *req; - /* break dest roi at height*/ - d_x_0 = d_x_1 = req->dst_rect.x; - d_w_0 = d_w_1 = req->dst_rect.w; - d_y_0 = req->dst_rect.y; - if (req->dst_rect.h % 32 == 3) - d_h_1 = (req->dst_rect.h - 3) / 2 - 1; - else - d_h_1 = (req->dst_rect.h - 1) / 2 - 1; - d_h_0 = req->dst_rect.h - d_h_1; - d_y_1 = d_y_0 + d_h_0; - if (req->dst_rect.h == 3) { - d_h_1 = 2; - d_h_0 = 2; - d_y_1 = d_y_0 + 1; - } - /* break source roi */ - if (splitreq.flags & MDP_ROT_90) { - s_y_0 = s_y_1 = req->src_rect.y; - s_h_0 = s_h_1 = req->src_rect.h; - s_x_0 = req->src_rect.x; - s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h; - s_w_0 = req->src_rect.w - s_w_1; - s_x_1 = s_x_0 + s_w_0; - if (d_h_1 >= 8 * s_w_1) { - s_w_1++; - s_x_1--; - } - } else { - s_x_0 = s_x_1 = req->src_rect.x; - s_w_0 = s_w_1 = req->src_rect.w; - s_y_0 = req->src_rect.y; - s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h; - s_h_0 = req->src_rect.h - s_h_1; - s_y_1 = s_y_0 + s_h_0; - if (d_h_1 >= 8 * s_h_1) { - s_h_1++; - s_y_1--; - } - } - - /* blit first region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } else { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); + ret = mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue); if (ret) - return ret; - - /* blit second region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } else { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); + mdp_ppp_dump_debug(mdp); return ret; } -/* Splits a blit into two vertical stripes. Used to work around MDP bugs */ -int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +static int get_img(struct mdp_img *img, struct fb_info *info, + unsigned long *start, unsigned long *len, + struct file** filep) +{ + int put_needed, ret = 0; + struct file *file; + unsigned long vstart; + + if (img->memory_id & 0x40000000) + { + struct fb_info *fb = registered_fb[img->memory_id & 0x0000FFFF]; + if (fb) + { + *start = fb->fix.smem_start; + *len = fb->fix.smem_len; + } + *filep = NULL; + return 0; + } + + if (!get_pmem_file(img->memory_id, start, &vstart, len, filep)) + return 0; + else if (!get_msm_hw3d_file(img->memory_id, &img->offset, start, len, + filep)) + return 0; + + file = fget_light(img->memory_id, &put_needed); + if (file == NULL) + return -1; + + if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) { + *start = info->fix.smem_start; + *len = info->fix.smem_len; + ret = 0; + } else + ret = -1; + fput_light(file, put_needed); + + return ret; +} +void put_img(struct file *p_src_file) +{ +#ifdef CONFIG_ANDROID_PMEM + if (p_src_file) + put_pmem_file(p_src_file); +#else + if (is_msm_hw3d_file(p_src_file)) + put_msm_hw3d_file(p_src_file); +#endif +} + +static void dump_req(struct mdp_blit_req *req, + unsigned long src_start, unsigned long src_len, + unsigned long dst_start, unsigned long dst_len) +{ + pr_err("flags: 0x%x\n", req->flags); + pr_err("src_start: 0x%08lx\n", src_start); + pr_err("src_len: 0x%08lx\n", src_len); + pr_err("src.offset: 0x%x\n", req->src.offset); + pr_err("src.format: 0x%x\n", req->src.format); + pr_err("src.width: %d\n", req->src.width); + pr_err("src.height: %d\n", req->src.height); + pr_err("src_rect.x: %d\n", req->src_rect.x); + pr_err("src_rect.y: %d\n", req->src_rect.y); + pr_err("src_rect.w: %d\n", req->src_rect.w); + pr_err("src_rect.h: %d\n", req->src_rect.h); + + pr_err("dst_start: 0x%08lx\n", dst_start); + pr_err("dst_len: 0x%08lx\n", dst_len); + pr_err("dst.offset: 0x%x\n", req->dst.offset); + pr_err("dst.format: 0x%x\n", req->dst.format); + pr_err("dst.width: %d\n", req->dst.width); + pr_err("dst.height: %d\n", req->dst.height); + pr_err("dst_rect.x: %d\n", req->dst_rect.x); + pr_err("dst_rect.y: %d\n", req->dst_rect.y); + pr_err("dst_rect.w: %d\n", req->dst_rect.w); + pr_err("dst_rect.h: %d\n", req->dst_rect.h); +} + +int mdp_ppp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) { int ret; - struct mdp_blit_req splitreq; - int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; - int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; - splitreq = *req; - - /* break dest roi at width*/ - d_y_0 = d_y_1 = req->dst_rect.y; - d_h_0 = d_h_1 = req->dst_rect.h; - d_x_0 = req->dst_rect.x; - if (req->dst_rect.w % 32 == 6) - d_w_1 = req->dst_rect.w / 2 - 1; - else if (req->dst_rect.w % 2 == 0) - d_w_1 = req->dst_rect.w / 2; - else if (req->dst_rect.w % 32 == 3) - d_w_1 = (req->dst_rect.w - 3) / 2 - 1; - else - d_w_1 = (req->dst_rect.w - 1) / 2 - 1; - d_w_0 = req->dst_rect.w - d_w_1; - d_x_1 = d_x_0 + d_w_0; - if (req->dst_rect.w == 3) { - d_w_1 = 2; - d_w_0 = 2; - d_x_1 = d_x_0 + 1; + mdp->enable_irq(mdp, DL0_ROI_DONE); + ret = process_blit(mdp, req, src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (unlikely(ret)) { + mdp->disable_irq(mdp, DL0_ROI_DONE); + return ret; } - - /* break src roi at height or width*/ - if (splitreq.flags & MDP_ROT_90) { - s_x_0 = s_x_1 = req->src_rect.x; - s_w_0 = s_w_1 = req->src_rect.w; - s_y_0 = req->src_rect.y; - s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w; - s_h_0 = req->src_rect.h - s_h_1; - s_y_1 = s_y_0 + s_h_0; - if (d_w_1 >= 8 * s_h_1) { - s_h_1++; - s_y_1--; - } - } else { - s_y_0 = s_y_1 = req->src_rect.y; - s_h_0 = s_h_1 = req->src_rect.h; - s_x_0 = req->src_rect.x; - s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w; - s_w_0 = req->src_rect.w - s_w_1; - s_x_1 = s_x_0 + s_w_0; - if (d_w_1 >= 8 * s_w_1) { - s_w_1++; - s_x_1--; - } + ret = mdp_ppp_wait(mdp); + if (unlikely(ret)) { + printk(KERN_ERR "%s: failed!\n", __func__); + pr_err("original request:\n"); + dump_req(mdp->req, src_start, src_len, dst_start, dst_len); + pr_err("dead request:\n"); + dump_req(req, src_start, src_len, dst_start, dst_len); + BUG(); + return ret; } + return 0; +} - /* blit first region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; - } else { - splitreq.src_rect.h = s_h_0; - splitreq.src_rect.y = s_y_0; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_0; - splitreq.src_rect.w = s_w_0; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } +int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb, + struct mdp_blit_req *req) +{ + int ret; + unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0; + struct file *src_file = 0, *dst_file = 0; - if (unlikely((splitreq.dst_rect.h != 1) && - ((splitreq.dst_rect.h % 32 == 3) || - (splitreq.dst_rect.h % 32) == 1))) - ret = mdp_ppp_blit_split_height(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - else - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); + ret = mdp_ppp_validate_blit(mdp, req); if (ret) return ret; - /* blit second region */ - if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) || - ((splitreq.flags & MDP_ROT_MASK) == 0x0)) { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_1; - splitreq.dst_rect.y = d_y_1; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_1; - splitreq.dst_rect.w = d_w_1; - } else { - splitreq.src_rect.h = s_h_1; - splitreq.src_rect.y = s_y_1; - splitreq.dst_rect.h = d_h_0; - splitreq.dst_rect.y = d_y_0; - splitreq.src_rect.x = s_x_1; - splitreq.src_rect.w = s_w_1; - splitreq.dst_rect.x = d_x_0; - splitreq.dst_rect.w = d_w_0; + /* do this first so that if this fails, the caller can always + * safely call put_img */ + if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) { + printk(KERN_ERR "mdp_ppp: could not retrieve src image from " + "memory\n"); + return -EINVAL; } - if (unlikely((splitreq.dst_rect.h != 1) && - ((splitreq.dst_rect.h % 32 == 3) || - (splitreq.dst_rect.h % 32) == 1))) - ret = mdp_ppp_blit_split_height(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); - else - ret = mdp_blit_and_wait(mdp, &splitreq, - src_file, src_start, src_len, - dst_file, dst_start, dst_len); + if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) { + printk(KERN_ERR "mdp_ppp: could not retrieve dst image from " + "memory\n"); + put_img(src_file); + return -EINVAL; + } + mutex_lock(&mdp_mutex); + + /* transp_masking unimplemented */ + req->transp_mask = MDP_TRANSP_NOP; + mdp->req = req; + + ret = mdp_ppp_do_blit(mdp, req, src_file, src_start, src_len, + dst_file, dst_start, dst_len); + + put_img(src_file); + put_img(dst_file); + mutex_unlock(&mdp_mutex); return ret; -} \ No newline at end of file +} + +void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask) +{ + if (mask & DL0_ROI_DONE) + wake_up(&mdp_ppp_waitqueue); +} + + diff --git a/drivers/video/msm/mdp_ppp.h b/drivers/video/msm/mdp_ppp.h index 357a7f06..03a15068 100644 --- a/drivers/video/msm/mdp_ppp.h +++ b/drivers/video/msm/mdp_ppp.h @@ -16,7 +16,6 @@ #define _VIDEO_MSM_MDP_PPP_H_ #include -#define PPP_DUMP_BLITS 0 struct ppp_regs { uint32_t src0; @@ -63,40 +62,57 @@ struct ppp_regs { struct mdp_info; struct mdp_rect; struct mdp_blit_req; +struct fb_info; -void mdp_ppp_init_scale(const struct mdp_info *mdp); -int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, - struct mdp_rect *src_rect, struct mdp_rect *dst_rect, - uint32_t src_format, uint32_t dst_format); -int mdp_ppp_load_blur(const struct mdp_info *mdp); -void mdp_dump_blit(struct mdp_blit_req *req); - - -#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302) -int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len); -int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len); - -#if defined(CONFIG_MSM_MDP302) -int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); -#else -static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, - struct ppp_regs *regs) -{ - return 0; -} -#endif - -#else -int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); -#endif - +#ifdef CONFIG_FB_MSM_MDP_PPP int mdp_get_bytes_per_pixel(int format); -int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, - struct file *src_file, unsigned long src_start, unsigned long src_len, - struct file *dst_file, unsigned long dst_start, unsigned long dst_len); +int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb, + struct mdp_blit_req *req); +void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask); +int mdp_ppp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, + unsigned long src_len, struct file *dst_file, + unsigned long dst_start, unsigned long dst_len); + +/* these must be provided by h/w specific ppp files */ +void mdp_ppp_init_scale(struct mdp_info *mdp); +int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs, + struct mdp_rect *src_rect, struct mdp_rect *dst_rect, + uint32_t src_format, uint32_t dst_format); +int mdp_ppp_load_blur(struct mdp_info *mdp); +int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs); +int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req); +int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, + unsigned long src_len, struct file *dst_file, + unsigned long dst_start, unsigned long dst_len); + +#else + +static inline int mdp_get_bytes_per_pixel(int format) { return -1; } +static inline int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb, + struct mdp_blit_req *req) { return -EINVAL; } +static inline void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask) {} +static inline int mdp_ppp_blit_and_wait(struct mdp_info *mdp, + struct mdp_blit_req *req, struct file *src_file, + unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, + unsigned long dst_len) { return 0; } + +static inline void mdp_ppp_init_scale(struct mdp_info *mdp) {} +static inline int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs, + struct mdp_rect *src_rect, struct mdp_rect *dst_rect, + uint32_t src_format, uint32_t dst_format) { return 0; } +static inline int mdp_ppp_load_blur(struct mdp_info *mdp) { return 0; } +static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs) { return 0; } +static inline int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req) { return -EINVAL; } +static inline int mdp_ppp_do_blit(struct mdp_info *mdp, + struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, + unsigned long src_len, struct file *dst_file, + unsigned long dst_start, unsigned long dst_len) { return 0; } + + +#endif /* CONFIG_FB_MSM_MDP_PPP */ #endif /* _VIDEO_MSM_MDP_PPP_H_ */ diff --git a/drivers/video/msm/mdp_ppp22.c b/drivers/video/msm/mdp_ppp22.c index 02fca9a3..dc4cc279 100644 --- a/drivers/video/msm/mdp_ppp22.c +++ b/drivers/video/msm/mdp_ppp22.c @@ -1016,7 +1016,7 @@ static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin, return 0; } -int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, +int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs, struct mdp_rect *src_rect, struct mdp_rect *dst_rect, uint32_t src_format, uint32_t dst_format) { @@ -1070,7 +1070,7 @@ int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, } -int mdp_ppp_load_blur(const struct mdp_info *mdp) +int mdp_ppp_load_blur(struct mdp_info *mdp) { if (!(downscale_x_table == MDP_DOWNSCALE_BLUR && downscale_y_table == MDP_DOWNSCALE_BLUR)) { @@ -1082,10 +1082,64 @@ int mdp_ppp_load_blur(const struct mdp_info *mdp) return 0; } -void mdp_ppp_init_scale(const struct mdp_info *mdp) +void mdp_ppp_init_scale(struct mdp_info *mdp) { downscale_x_table = MDP_DOWNSCALE_MAX; downscale_y_table = MDP_DOWNSCALE_MAX; load_table(mdp, mdp_upscale_table, ARRAY_SIZE(mdp_upscale_table)); } + +int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req) +{ + /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */ + if (unlikely(req->src_rect.h == 0 || + req->src_rect.w == 0)) { + pr_info("mdp_ppp: src img of zero size!\n"); + return -EINVAL; + } + if (unlikely(req->dst_rect.h == 0 || + req->dst_rect.w == 0)) + return -EINVAL; + + return 0; +} + +int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, + unsigned long src_len, struct file *dst_file, + unsigned long dst_start, unsigned long dst_len) +{ + int ret; + + if (unlikely((req->transp_mask != MDP_TRANSP_NOP || + req->alpha != MDP_ALPHA_NOP || + HAS_ALPHA(req->src.format)) && + (req->flags & MDP_ROT_90 && + req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) { + int i; + unsigned int tiles = req->dst_rect.h / 16; + unsigned int remainder = req->dst_rect.h % 16; + req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h; + req->dst_rect.h = 16; + for (i = 0; i < tiles; i++) { + ret = mdp_ppp_blit_and_wait(mdp, req, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (ret) + goto end; + req->dst_rect.y += 16; + req->src_rect.x += req->src_rect.w; + } + if (!remainder) + goto end; + req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h; + req->dst_rect.h = remainder; + } + + ret = mdp_ppp_blit_and_wait(mdp, req, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); +end: + return ret; +} diff --git a/drivers/video/msm/mdp_ppp31.c b/drivers/video/msm/mdp_ppp31.c index cc7b513c..fa36002e 100644 --- a/drivers/video/msm/mdp_ppp31.c +++ b/drivers/video/msm/mdp_ppp31.c @@ -276,7 +276,7 @@ static int scale_idx(int factor) return idx; } -int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, +int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs, struct mdp_rect *src_rect, struct mdp_rect *dst_rect, uint32_t src_format, uint32_t dst_format) { @@ -319,16 +319,319 @@ int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs, return 0; } -int mdp_ppp_load_blur(const struct mdp_info *mdp) +int mdp_ppp_load_blur(struct mdp_info *mdp) { return -ENOTSUPP; } -void mdp_ppp_init_scale(const struct mdp_info *mdp) +int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs) +{ + return 0; +} + +void mdp_ppp_init_scale(struct mdp_info *mdp) { int scale; for (scale = 0; scale < MDP_SCALE_MAX; ++scale) load_table(mdp, scale, 0); } +/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */ +static int blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +{ + int ret; + struct mdp_blit_req splitreq; + int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; + int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; + splitreq = *req; + /* break dest roi at height*/ + d_x_0 = d_x_1 = req->dst_rect.x; + d_w_0 = d_w_1 = req->dst_rect.w; + d_y_0 = req->dst_rect.y; + if (req->dst_rect.h % 32 == 3) + d_h_1 = (req->dst_rect.h - 3) / 2 - 1; + else + d_h_1 = (req->dst_rect.h - 1) / 2 - 1; + d_h_0 = req->dst_rect.h - d_h_1; + d_y_1 = d_y_0 + d_h_0; + if (req->dst_rect.h == 3) { + d_h_1 = 2; + d_h_0 = 2; + d_y_1 = d_y_0 + 1; + } + /* break source roi */ + if (splitreq.flags & MDP_ROT_90) { + s_y_0 = s_y_1 = req->src_rect.y; + s_h_0 = s_h_1 = req->src_rect.h; + s_x_0 = req->src_rect.x; + s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h; + s_w_0 = req->src_rect.w - s_w_1; + s_x_1 = s_x_0 + s_w_0; + if (d_h_1 >= 8 * s_w_1) { + s_w_1++; + s_x_1--; + } + } else { + s_x_0 = s_x_1 = req->src_rect.x; + s_w_0 = s_w_1 = req->src_rect.w; + s_y_0 = req->src_rect.y; + s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h; + s_h_0 = req->src_rect.h - s_h_1; + s_y_1 = s_y_0 + s_h_0; + if (d_h_1 >= 8 * s_h_1) { + s_h_1++; + s_y_1--; + } + } + + /* blit first region */ + if (((splitreq.flags & 0x07) == MDP_ROT_90) || + ((splitreq.flags & 0x07) == 0x0)) { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } else { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } + ret = mdp_ppp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (ret) + return ret; + + /* blit second region */ + if (((splitreq.flags & 0x07) == MDP_ROT_90) || + ((splitreq.flags & 0x07) == 0x0)) { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } else { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } + ret = mdp_ppp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + return ret; +} + +/* Splits a blit into two vertical stripes. Used to work around MDP bugs */ +static int blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, unsigned long src_len, + struct file *dst_file, unsigned long dst_start, unsigned long dst_len) +{ + int ret; + struct mdp_blit_req splitreq; + int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1; + int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1; + splitreq = *req; + + /* break dest roi at width*/ + d_y_0 = d_y_1 = req->dst_rect.y; + d_h_0 = d_h_1 = req->dst_rect.h; + d_x_0 = req->dst_rect.x; + if (req->dst_rect.w % 32 == 6) + d_w_1 = req->dst_rect.w / 2 - 1; + else if (req->dst_rect.w % 2 == 0) + d_w_1 = req->dst_rect.w / 2; + else if (req->dst_rect.w % 32 == 3) + d_w_1 = (req->dst_rect.w - 3) / 2 - 1; + else + d_w_1 = (req->dst_rect.w - 1) / 2 - 1; + d_w_0 = req->dst_rect.w - d_w_1; + d_x_1 = d_x_0 + d_w_0; + if (req->dst_rect.w == 3) { + d_w_1 = 2; + d_w_0 = 2; + d_x_1 = d_x_0 + 1; + } + + /* break src roi at height or width*/ + if (splitreq.flags & MDP_ROT_90) { + s_x_0 = s_x_1 = req->src_rect.x; + s_w_0 = s_w_1 = req->src_rect.w; + s_y_0 = req->src_rect.y; + s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w; + s_h_0 = req->src_rect.h - s_h_1; + s_y_1 = s_y_0 + s_h_0; + if (d_w_1 >= 8 * s_h_1) { + s_h_1++; + s_y_1--; + } + } else { + s_y_0 = s_y_1 = req->src_rect.y; + s_h_0 = s_h_1 = req->src_rect.h; + s_x_0 = req->src_rect.x; + s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w; + s_w_0 = req->src_rect.w - s_w_1; + s_x_1 = s_x_0 + s_w_0; + if (d_w_1 >= 8 * s_w_1) { + s_w_1++; + s_x_1--; + } + } + + /* blit first region */ + if (((splitreq.flags & 0x07) == MDP_ROT_270) || + ((splitreq.flags & 0x07) == 0x0)) { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } else { + splitreq.src_rect.h = s_h_0; + splitreq.src_rect.y = s_y_0; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_0; + splitreq.src_rect.w = s_w_0; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } + + if (unlikely((splitreq.dst_rect.h != 1) && + ((splitreq.dst_rect.h % 32 == 3) || + (splitreq.dst_rect.h % 32) == 1))) + ret = blit_split_height(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + else + ret = mdp_ppp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + if (ret) + return ret; + + /* blit second region */ + if (((splitreq.flags & 0x07) == MDP_ROT_270) || + ((splitreq.flags & 0x07) == 0x0)) { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_1; + splitreq.dst_rect.y = d_y_1; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_1; + splitreq.dst_rect.w = d_w_1; + } else { + splitreq.src_rect.h = s_h_1; + splitreq.src_rect.y = s_y_1; + splitreq.dst_rect.h = d_h_0; + splitreq.dst_rect.y = d_y_0; + splitreq.src_rect.x = s_x_1; + splitreq.src_rect.w = s_w_1; + splitreq.dst_rect.x = d_x_0; + splitreq.dst_rect.w = d_w_0; + } + + if (unlikely((splitreq.dst_rect.h != 1) && + ((splitreq.dst_rect.h % 32 == 3) || + (splitreq.dst_rect.h % 32) == 1))) + ret = blit_split_height(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + else + ret = mdp_ppp_blit_and_wait(mdp, &splitreq, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + return ret; +} + + +int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req) +{ + if (req->flags & MDP_ROT_90) { + if (unlikely(((req->dst_rect.h == 1) && + ((req->src_rect.w != 1) || + (req->dst_rect.w != req->src_rect.h))) || + ((req->dst_rect.w == 1) && ((req->src_rect.h != 1) || + (req->dst_rect.h != req->src_rect.w))))) { + pr_err("mpd_ppp: error scaling when size is 1!\n"); + return -EINVAL; + } + } else { + if (unlikely(((req->dst_rect.w == 1) && + ((req->src_rect.w != 1) || + (req->dst_rect.h != req->src_rect.h))) || + ((req->dst_rect.h == 1) && ((req->src_rect.h != 1) || + (req->dst_rect.h != req->src_rect.h))))) { + pr_err("mpd_ppp: error scaling when size is 1!\n"); + return -EINVAL; + } + } + + /* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */ + if (unlikely(req->src_rect.h == 0 || + req->src_rect.w == 0)) { + pr_info("mdp_ppp: src img of zero size!\n"); + return -EINVAL; + } + if (unlikely(req->dst_rect.h == 0 || + req->dst_rect.w == 0)) + return -EINVAL; + + return 0; +} + +int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req, + struct file *src_file, unsigned long src_start, + unsigned long src_len, struct file *dst_file, + unsigned long dst_start, unsigned long dst_len) +{ + int ret; + + /* Workarounds for MDP 3.1 hardware bugs */ + if (unlikely((mdp_get_bytes_per_pixel(req->dst.format) == 4) && + (req->dst_rect.w != 1) && + (((req->dst_rect.w % 8) == 6) || + ((req->dst_rect.w % 32) == 3) || + ((req->dst_rect.w % 32) == 1)))) { + ret = blit_split_width(mdp, req, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + goto end; + } else if (unlikely((req->dst_rect.w != 1) && (req->dst_rect.h != 1) && + ((req->dst_rect.h % 32) == 3 || + (req->dst_rect.h % 32) == 1))) { + ret = blit_split_height(mdp, req, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); + goto end; + } + + ret = mdp_ppp_blit_and_wait(mdp, req, + src_file, src_start, src_len, + dst_file, dst_start, dst_len); +end: + return ret; +} diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c index aa27389d..82e110ce 100644 --- a/drivers/video/msm/msm_fb.c +++ b/drivers/video/msm/msm_fb.c @@ -33,11 +33,17 @@ #include #include #include +#include "mdp_hw.h" extern void start_drawing_late_resume(struct early_suspend *h); static void msmfb_resume_handler(struct early_suspend *h); static void msmfb_resume(struct work_struct *work); +#ifdef CONFIG_MSM_HDMI +void hdmi_DoBlit(int offset); +int hdmi_usePanelSync(void); +#endif + #define MSMFB_DEBUG 1 #ifdef CONFIG_FB_MSM_LOGO #define INIT_IMAGE_FILE "/logo.rle" @@ -59,6 +65,11 @@ extern int load_565rle_image(char *filename); #define BLIT_TIME 0x4 #define SHOW_UPDATES 0x8 +#ifdef CONFIG_PANEL_SELF_REFRESH +extern struct panel_icm_info *panel_icm; +extern wait_queue_head_t panel_update_wait_queue; +#endif + #define DLOG(mask, fmt, args...) \ do { \ if ((msmfb_debug_mask | SUSPEND_RESUME) & mask) \ @@ -72,6 +83,7 @@ module_param_named(msmfb_debug_mask, msmfb_debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP); struct mdp_device *mdp; +static atomic_t mdpclk_on = ATOMIC_INIT(1); struct msmfb_info { struct fb_info *fb; @@ -91,9 +103,13 @@ struct msmfb_info { int ebottom; /* exclusive */ } update_info; char *black; - +#ifdef CONFIG_HTC_ONMODE_CHARGING + struct early_suspend onchg_earlier_suspend; + struct early_suspend onchg_suspend; +#endif struct early_suspend earlier_suspend; struct early_suspend early_suspend; + struct wake_lock idle_lock; spinlock_t update_lock; struct mutex panel_init_lock; @@ -166,7 +182,7 @@ static int msmfb_release(struct fb_info *info, int user) /* Called from dma interrupt handler, must not sleep */ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) { - unsigned long irq_flags; + unsigned long irq_flags=0; struct msmfb_info *msmfb = container_of(callback, struct msmfb_info, dma_callback); #if PRINT_FPS @@ -178,6 +194,7 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback) spin_lock_irqsave(&msmfb->update_lock, irq_flags); msmfb->frame_done = msmfb->frame_requested; + if (msmfb->sleeping == UPDATING && msmfb->frame_done == msmfb->update_frame) { DLOG(SUSPEND_RESUME, "full update completed\n"); @@ -203,7 +220,7 @@ static int msmfb_start_dma(struct msmfb_info *msmfb) { uint32_t x, y, w, h; unsigned addr; - unsigned long irq_flags; + unsigned long irq_flags=0; uint32_t yoffset; s64 time_since_request; struct msm_panel_data *panel = msmfb->panel; @@ -230,11 +247,13 @@ static int msmfb_start_dma(struct msmfb_info *msmfb) y = msmfb->update_info.top; w = msmfb->update_info.eright - x; h = msmfb->update_info.ebottom - y; - +#if 0 /* zeusk: */ +;;;;;;ASD #if defined(CONFIG_FRAMEBUFFER_CONSOLE) x = 0; y = 0; w = msmfb->xres; h = msmfb->yres; #endif - +ASD;;;;;; +#endif yoffset = msmfb->yoffset; msmfb->update_info.left = msmfb->xres + 1; msmfb->update_info.top = msmfb->yres + 1; @@ -287,7 +306,10 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, { struct msmfb_info *msmfb = info->par; struct msm_panel_data *panel = msmfb->panel; - unsigned long irq_flags; +#ifdef CONFIG_PANEL_SELF_REFRESH + struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel); +#endif + unsigned long irq_flags=0; int sleeping; int retry = 1; #if PRINT_FPS @@ -300,16 +322,21 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top, DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n", left, top, eright, ebottom, yoffset, pan_display); -#if !defined(CONFIG_MACH_HTCLEO) - // For some reason we need to remove it here, state is 1, we have to look later to this problem - if (msmfb->sleeping != AWAKE) - DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping); +#ifdef CONFIG_PANEL_SELF_REFRESH + if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) { + spin_lock_irqsave(&panel_icm->lock, irq_flags); + panel_icm->panel_update = 1; + spin_unlock_irqrestore(&panel_icm->lock, irq_flags); + wake_up(&panel_update_wait_queue); + } #endif #if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR)) /* Jay, 8/1/09' */ msmfb_set_var(msmfb->fb->screen_base, yoffset); #endif + if (msmfb->sleeping != AWAKE) + DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping); restart: spin_lock_irqsave(&msmfb->update_lock, irq_flags); @@ -401,19 +428,35 @@ restart: msmfb->yoffset); spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); - /* if the panel is all the way on wait for vsync, otherwise sleep - * for 16 ms (long enough for the dma to panel) and then begin dma */ - msmfb->vsync_request_time = ktime_get(); - if (panel->request_vsync && (sleeping == AWAKE)) { - wake_lock_timeout(&msmfb->idle_lock, HZ/4); - panel->request_vsync(panel, &msmfb->vsync_callback); - } else { - if (!hrtimer_active(&msmfb->fake_vsync)) { - hrtimer_start(&msmfb->fake_vsync, - ktime_set(0, NSEC_PER_SEC/60), - HRTIMER_MODE_REL); - } - } +#ifdef CONFIG_MSM_HDMI + if (!hdmi_usePanelSync()) + { + msmfb->vsync_request_time = ktime_get(); + msmfb_start_dma(msmfb); + } + else + { +#endif + /* if the panel is all the way on wait for vsync, otherwise sleep + * for 16 ms (long enough for the dma to panel) and then begin dma */ + msmfb->vsync_request_time = ktime_get(); + if (panel->request_vsync && (sleeping == AWAKE)) { + wake_lock_timeout(&msmfb->idle_lock, HZ/4); + panel->request_vsync(panel, &msmfb->vsync_callback); + } else { + if (!hrtimer_active(&msmfb->fake_vsync)) { + hrtimer_start(&msmfb->fake_vsync, + ktime_set(0, NSEC_PER_SEC/60), + HRTIMER_MODE_REL); + } + } +#ifdef CONFIG_MSM_HDMI + } + + /* We did the DMA, now blit the data to the other display */ + hdmi_DoBlit(msmfb->xres * msmfb->yoffset * BYTES_PER_PIXEL(msmfb)); +#endif + return; } static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top, @@ -427,7 +470,7 @@ static void power_on_panel(struct work_struct *work) struct msmfb_info *msmfb = container_of(work, struct msmfb_info, resume_work); struct msm_panel_data *panel = msmfb->panel; - unsigned long irq_flags; + unsigned long irq_flags=0; mutex_lock(&msmfb->panel_init_lock); DLOG(SUSPEND_RESUME, "turning on panel\n"); if (msmfb->sleeping == UPDATING) { @@ -447,34 +490,33 @@ error: mutex_unlock(&msmfb->panel_init_lock); } -static BLOCKING_NOTIFIER_HEAD(display_chain_head); -int register_display_notifier(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&display_chain_head, nb); -} -static int display_notifier_callback(struct notifier_block *nfb, - unsigned long action, - void *ignored) -{ - struct msmfb_info *msm_fb = (struct msmfb_info *)ignored; - +static BLOCKING_NOTIFIER_HEAD(display_chain_head); +int register_display_notifier(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&display_chain_head, nb); +} +static int display_notifier_callback(struct notifier_block *nfb, + unsigned long action, + void *ignored) +{ + //struct msmfb_info *msm_fb = (struct msmfb_info *)ignored; + switch (action) { case NOTIFY_MSM_FB: - printk(KERN_DEBUG "NOTIFY_MSM_FB\n"); - msmfb_resume(&msm_fb->early_suspend); - break; + printk(KERN_DEBUG "NOTIFY_MSM_FB\n"); + //msmfb_resume(&msm_fb->early_suspend); + break; case NOTIFY_POWER: - /* nothing to do */ - break; + /* nothing to do */ + break; default: - printk(KERN_ERR "%s: unknown action in 0x%lx\n", - __func__, action); - return NOTIFY_BAD; + printk(KERN_ERR "%s: unknown action in 0x%lx\n", + __func__, action); + return NOTIFY_BAD; } return NOTIFY_OK; -} +} -/* -------------------------------------------------------------------------- */ #ifdef CONFIG_HAS_EARLYSUSPEND /* turn off the panel */ static void msmfb_earlier_suspend(struct early_suspend *h) @@ -482,7 +524,7 @@ static void msmfb_earlier_suspend(struct early_suspend *h) struct msmfb_info *msmfb = container_of(h, struct msmfb_info, earlier_suspend); struct msm_panel_data *panel = msmfb->panel; - unsigned long irq_flags; + unsigned long irq_flags=0; mutex_lock(&msmfb->panel_init_lock); msmfb->sleeping = SLEEPING; @@ -513,6 +555,8 @@ static void msmfb_suspend(struct early_suspend *h) overlay_event.event_wait, (overlay_event.waked_up == ~USE_OVERLAY), 10*HZ); + /*wait until USE_OVERLAY flag is off and set mdpclk_on as off*/ + atomic_set(&mdpclk_on, 0); pr_info("wait event : %X\n", overlay_event.waked_up); #endif panel->suspend(panel); @@ -523,17 +567,81 @@ static void msmfb_suspend(struct early_suspend *h) static void msmfb_resume_handler(struct early_suspend *h) { struct msmfb_info *msmfb = container_of(h, struct msmfb_info, - early_suspend); + early_suspend); +#ifdef CONFIG_HTC_ONMODE_CHARGING + if (msmfb->fb_resumed == 1) { + DLOG(SUSPEND_RESUME, "fb is resumed by onchg. skip resume\n"); + return; + } +#endif queue_work(msmfb->resume_workqueue, &msmfb->msmfb_resume_work); wait_event_interruptible_timeout(msmfb->frame_wq, msmfb->fb_resumed==1,HZ/2); } +#ifdef CONFIG_HTC_ONMODE_CHARGING +static void msmfb_onchg_earlier_suspend(struct early_suspend *h) +{ + struct msmfb_info *msmfb = container_of(h, struct msmfb_info, + onchg_earlier_suspend); + + struct msm_panel_data *panel = msmfb->panel; + unsigned long irq_flags=0; + + mutex_lock(&msmfb->panel_init_lock); + msmfb->sleeping = SLEEPING; + wake_up(&msmfb->frame_wq); + spin_lock_irqsave(&msmfb->update_lock, irq_flags); + spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); + +#ifndef CONFIG_MSM_MDP40 + mdp->dma(mdp, virt_to_phys(msmfb->black), 0, + msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0, + NULL, panel->interface_type); + mdp->dma_wait(mdp, panel->interface_type); +#endif + wait_event_timeout(msmfb->frame_wq, + msmfb->frame_requested == msmfb->frame_done, HZ/10); + + /* turn off the panel */ + panel->blank(panel); +} + +static void msmfb_onchg_suspend(struct early_suspend *h) +{ + struct msmfb_info *msmfb = container_of(h, struct msmfb_info, + onchg_suspend); + struct msm_panel_data *panel = msmfb->panel; + /* suspend the panel */ +#ifdef CONFIG_FB_MSM_OVERLAY + /*check whether overlay done*/ + wait_event_interruptible_timeout( + overlay_event.event_wait, + (overlay_event.waked_up == ~USE_OVERLAY), + 10*HZ); + /*wait until USE_OVERLAY flag is off and set mdpclk_on as off*/ + atomic_set(&mdpclk_on, 0); + pr_info("wait event : %X\n", overlay_event.waked_up); +#endif + panel->suspend(panel); + msmfb->fb_resumed = 0; + mutex_unlock(&msmfb->panel_init_lock); +} + +static void msmfb_onchg_resume_handler(struct early_suspend *h) +{ + struct msmfb_info *msmfb = container_of(h, struct msmfb_info, + onchg_suspend); + queue_work(msmfb->resume_workqueue, &msmfb->msmfb_resume_work); + wait_event_interruptible_timeout(msmfb->frame_wq, msmfb->fb_resumed == 1, HZ/2); +} +#endif + static void msmfb_resume(struct work_struct *work) { struct msmfb_info *msmfb = container_of(work, struct msmfb_info, msmfb_resume_work); struct msm_panel_data *panel = msmfb->panel; - unsigned long irq_flags; + unsigned long irq_flags=0; if (panel->resume(panel)) { printk(KERN_INFO "msmfb: panel resume failed, not resuming " @@ -545,15 +653,16 @@ static void msmfb_resume(struct work_struct *work) msmfb->sleeping = WAKING; DLOG(SUSPEND_RESUME, "ready, waiting for full update\n"); spin_unlock_irqrestore(&msmfb->update_lock, irq_flags); - start_drawing_late_resume(NULL); msmfb->fb_resumed = 1; wake_up(&msmfb->frame_wq); + + atomic_set(&mdpclk_on, 1); } #endif static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) { - u32 size; + uint32_t size; if ((var->xres != info->var.xres) || (var->yres != info->var.yres) || @@ -625,28 +734,22 @@ int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect) { cfb_fillrect(p, rect); -#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width, rect->dy + rect->height); -#endif } static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area) { cfb_copyarea(p, area); -#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) msmfb_update(p, area->dx, area->dy, area->dx + area->width, area->dy + area->height); -#endif } static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image) { cfb_imageblit(p, image); -#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) msmfb_update(p, image->dx, image->dy, image->dx + image->width, image->dy + image->height); -#endif } @@ -705,6 +808,7 @@ static int msmfb_overlay_set(struct fb_info *info, void __user *p) if (copy_from_user(&req, p, sizeof(req))) return -EFAULT; + printk(KERN_INFO "%s(%d) dst rect info w=%d h=%d x=%d y=%d rotator=%d\n", __func__, __LINE__, req.dst_rect.w, req.dst_rect.h, req.dst_rect.x, req.dst_rect.y, req.user_data[0]); ret = mdp->overlay_set(mdp, info, &req); if (ret) { printk(KERN_ERR "%s:ioctl failed \n", @@ -764,7 +868,7 @@ DEFINE_MUTEX(mdp_ppp_lock); static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; - int ret; + int ret = 0; #if PRINT_BLIT_TIME ktime_t t1, t2; #endif @@ -788,41 +892,41 @@ static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg) break; #ifdef CONFIG_FB_MSM_OVERLAY case MSMFB_OVERLAY_GET: - printk("CONFIG_FB_MSM_OVERLAY\n"); - //down(&mdp_ppp_lock); ret = msmfb_overlay_get(p, argp); - //up(&mdp_ppp_lock); break; case MSMFB_OVERLAY_SET: - printk("MSMFB_OVERLAY_SET\n"); - //down(&mdp_ppp_lock); - ret = msmfb_overlay_set(p, argp); - mutex_lock(&overlay_event_lock); - overlay_event.waked_up = USE_OVERLAY; - mutex_unlock(&overlay_event_lock); - //up(&mdp_ppp_lock); + if(!atomic_read(&mdpclk_on)) { + printk(KERN_ERR "MSMFB_OVERLAY_SET during suspend\n"); + ret = -EINVAL; + } else { + mutex_lock(&overlay_event_lock); + overlay_event.waked_up = USE_OVERLAY; + mutex_unlock(&overlay_event_lock); + ret = msmfb_overlay_set(p, argp); + } + printk(KERN_INFO "MSMFB_OVERLAY_SET ret=%d\n", ret); break; case MSMFB_OVERLAY_UNSET: - printk("MSMFB_OVERLAY_UNSET\n"); - //down(&mdp_ppp_lock); ret = msmfb_overlay_unset(p, argp); mutex_lock(&overlay_event_lock); overlay_event.waked_up = ~USE_OVERLAY; wake_up(&overlay_event.event_wait); mutex_unlock(&overlay_event_lock); - //up(&mdp_ppp_lock); + printk(KERN_INFO "MSMFB_OVERLAY_UNSET ret=%d\n", ret); break; case MSMFB_OVERLAY_PLAY: - //down(&mdp_ppp_lock); - ret = msmfb_overlay_play(p, argp); - //up(&mdp_ppp_lock); + if(!atomic_read(&mdpclk_on)) { + printk(KERN_ERR "MSMFB_OVERLAY_PLAY during suspend\n"); + ret = -EINVAL; + } else + ret = msmfb_overlay_play(p, argp); break; #endif default: printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd); return -EINVAL; } - return 0; + return ret; } static struct fb_ops msmfb_ops = { @@ -856,7 +960,7 @@ static ssize_t debug_read(struct file *file, char __user *buf, size_t count, static char buffer[4096]; int n = 0; struct msmfb_info *msmfb = (struct msmfb_info *)file->private_data; - unsigned long irq_flags; + unsigned long irq_flags=0; spin_lock_irqsave(&msmfb->update_lock, irq_flags); n = scnprintf(buffer, debug_bufmax, "yoffset %d\n", msmfb->yoffset); @@ -880,7 +984,7 @@ static struct file_operations debug_fops = { }; #endif -#define BITS_PER_PIXEL 16 +#define BITS_PER_PIXEL_DEF 32 static void setup_fb_info(struct msmfb_info *msmfb) { @@ -904,8 +1008,9 @@ static void setup_fb_info(struct msmfb_info *msmfb) fb_info->var.height = msmfb->panel->fb_data->height; fb_info->var.xres_virtual = msmfb->xres; fb_info->var.yres_virtual = msmfb->yres * 2; - fb_info->var.bits_per_pixel = BITS_PER_PIXEL; + fb_info->var.bits_per_pixel = BITS_PER_PIXEL_DEF; fb_info->var.accel_flags = 0; + fb_info->var.reserved[4] = 60; fb_info->var.yoffset = 0; @@ -938,6 +1043,7 @@ static void setup_fb_info(struct msmfb_info *msmfb) fb_info->var.blue.msb_right = 0; mdp->set_output_format(mdp, fb_info->var.bits_per_pixel); + mdp->set_panel_size(mdp, msmfb->xres, msmfb->yres); r = fb_alloc_cmap(&fb_info->cmap, 16, 0); fb_info->pseudo_palette = PP; @@ -1027,7 +1133,7 @@ static int msmfb_probe(struct platform_device *pdev) spin_lock_init(&msmfb->update_lock); mutex_init(&msmfb->panel_init_lock); init_waitqueue_head(&msmfb->frame_wq); - msmfb->resume_workqueue = create_rt_workqueue("panel_on"); + msmfb->resume_workqueue = create_workqueue("panel_on"); if (msmfb->resume_workqueue == NULL) { printk(KERN_ERR "failed to create panel_on workqueue\n"); ret = -ENOMEM; @@ -1049,6 +1155,16 @@ static int msmfb_probe(struct platform_device *pdev) msmfb->earlier_suspend.suspend = msmfb_earlier_suspend; msmfb->earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; register_early_suspend(&msmfb->earlier_suspend); +#ifdef CONFIG_HTC_ONMODE_CHARGING + msmfb->onchg_suspend.suspend = msmfb_onchg_suspend; + msmfb->onchg_suspend.resume = msmfb_onchg_resume_handler; + msmfb->onchg_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB; + register_onchg_suspend(&msmfb->onchg_suspend); + + msmfb->onchg_earlier_suspend.suspend = msmfb_onchg_earlier_suspend; + msmfb->onchg_earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; + register_onchg_suspend(&msmfb->onchg_earlier_suspend); +#endif #endif #if MSMFB_DEBUG @@ -1082,10 +1198,10 @@ static int msmfb_probe(struct platform_device *pdev) #ifdef CONFIG_FB_MSM_LOGO if (!load_565rle_image(INIT_IMAGE_FILE)) { /* Flip buffer */ - msmfb->update_info.left = 0; + msmfb->update_info.left = 0; msmfb->update_info.top = 0; msmfb->update_info.eright = msmfb->xres; - msmfb->update_info.ebottom = msmfb->yres; + msmfb->update_info.ebottom = msmfb->yres; msmfb_pan_update(msmfb->fb, 0, 0, msmfb->xres, msmfb->yres, 0, 1); } diff --git a/include/linux/fb.h b/include/linux/fb.h index de9c722e..f4dc55ed 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -3,13 +3,31 @@ #include #include - struct dentry; /* Definitions of frame buffers */ #define FB_MAX 32 /* sufficient for now */ +struct fbcon_decor_iowrapper +{ + unsigned short vc; /* Virtual console */ + unsigned char origin; /* Point of origin of the request */ + void *data; +}; + +#ifdef __KERNEL__ +#ifdef CONFIG_COMPAT +#include +struct fbcon_decor_iowrapper32 +{ + unsigned short vc; /* Virtual console */ + unsigned char origin; /* Point of origin of the request */ + compat_uptr_t data; +}; +#endif /* CONFIG_COMPAT */ +#endif /* __KERNEL__ */ + /* ioctls 0x46 is 'F' */ #define FBIOGET_VSCREENINFO 0x4600 @@ -37,7 +55,24 @@ struct dentry; #define FBIOGET_HWCINFO 0x4616 #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 +#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper) +#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper) +#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper) +#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper) +#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper) +#ifdef __KERNEL__ +#ifdef CONFIG_COMPAT +#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32) +#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32) +#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32) +#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32) +#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32) +#endif /* CONFIG_COMPAT */ +#endif /* __KERNEL__ */ +#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */ +#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */ +#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */ #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ #define FB_TYPE_PLANES 1 /* Non interleaved planes */ @@ -282,6 +317,28 @@ struct fb_cmap { __u16 *transp; /* transparency, can be NULL */ }; +#ifdef __KERNEL__ +#ifdef CONFIG_COMPAT +struct fb_cmap32 { + __u32 start; + __u32 len; /* Number of entries */ + compat_uptr_t red; /* Red values */ + compat_uptr_t green; + compat_uptr_t blue; + compat_uptr_t transp; /* transparency, can be NULL */ +}; + +#define fb_cmap_from_compat(to, from) \ + (to).start = (from).start; \ + (to).len = (from).len; \ + (to).red = compat_ptr((from).red); \ + (to).green = compat_ptr((from).green); \ + (to).blue = compat_ptr((from).blue); \ + (to).transp = compat_ptr((from).transp) + +#endif /* CONFIG_COMPAT */ +#endif /* __KERNEL__ */ + struct fb_con2fbmap { __u32 console; __u32 framebuffer; @@ -363,6 +420,34 @@ struct fb_image { struct fb_cmap cmap; /* color map info */ }; +#ifdef __KERNEL__ +#ifdef CONFIG_COMPAT +struct fb_image32 { + __u32 dx; /* Where to place image */ + __u32 dy; + __u32 width; /* Size of image */ + __u32 height; + __u32 fg_color; /* Only used when a mono bitmap */ + __u32 bg_color; + __u8 depth; /* Depth of the image */ + const compat_uptr_t data; /* Pointer to image data */ + struct fb_cmap32 cmap; /* color map info */ +}; + +#define fb_image_from_compat(to, from) \ + (to).dx = (from).dx; \ + (to).dy = (from).dy; \ + (to).width = (from).width; \ + (to).height = (from).height; \ + (to).fg_color = (from).fg_color; \ + (to).bg_color = (from).bg_color; \ + (to).depth = (from).depth; \ + (to).data = compat_ptr((from).data); \ + fb_cmap_from_compat((to).cmap, (from).cmap) + +#endif /* CONFIG_COMPAT */ +#endif /* __KERNEL__ */ + /* * hardware cursor control */ @@ -403,6 +488,7 @@ struct fb_cursor { #include #include #include +#include #include struct vm_area_struct; @@ -543,6 +629,8 @@ struct fb_cursor_user { #define FB_EVENT_GET_REQ 0x0D /* Unbind from the console if possible */ #define FB_EVENT_FB_UNBIND 0x0E +/* CONSOLE-SPECIFIC: remap all consoles to new fb - for vga switcheroo */ +#define FB_EVENT_REMAP_ALL_CONSOLE 0x0F struct fb_event { struct fb_info *info; @@ -606,6 +694,12 @@ struct fb_deferred_io { * LOCKING NOTE: those functions must _ALL_ be called with the console * semaphore held, this is the only suitable locking mechanism we have * in 2.6. Some may be called at interrupt time at this point though. + * + * The exception to this is the debug related hooks. Putting the fb + * into a debug state (e.g. flipping to the kernel console) and restoring + * it must be done in a lock-free manner, so low level drivers should + * keep track of the initial console (if applicable) and may need to + * perform direct, unlocked hardware writes in these hooks. */ struct fb_ops { @@ -675,6 +769,10 @@ struct fb_ops { /* teardown any resources to do with this framebuffer */ void (*fb_destroy)(struct fb_info *info); + + /* called at KDB enter and leave time to prepare the console */ + int (*fb_debug_enter)(struct fb_info *info); + int (*fb_debug_leave)(struct fb_info *info); }; #ifdef CONFIG_FB_TILEBLITTING @@ -763,6 +861,7 @@ struct fb_tile_ops { * takes over; acceleration engine should be in a quiescent state */ /* hints */ +#define FBINFO_VIRTFB 0x0004 /* FB is System RAM, not device. */ #define FBINFO_PARTIAL_PAN_OK 0x0040 /* otw use pan only for double-buffering */ #define FBINFO_READS_FAST 0x0080 /* soft-copy faster than rendering */ @@ -784,8 +883,6 @@ struct fb_tile_ops { #define FBINFO_MISC_USEREVENT 0x10000 /* event request from userspace */ #define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */ -#define FBINFO_MISC_FIRMWARE 0x40000 /* a replaceable firmware - inited framebuffer */ /* A driver may set this flag to indicate that it does want a set_par to be * called every time when fbcon_switch is executed. The advantage is that with @@ -799,6 +896,8 @@ struct fb_tile_ops { */ #define FBINFO_MISC_ALWAYS_SETPAR 0x40000 +/* where the fb is a firmware driver, and can be replaced with a proper one */ +#define FBINFO_MISC_FIRMWARE 0x80000 /* * Host and GPU endianness differ. */ @@ -810,6 +909,10 @@ struct fb_tile_ops { */ #define FBINFO_BE_MATH 0x100000 +/* report to the VT layer that this fb driver can accept forced console + output like oopses */ +#define FBINFO_CAN_FORCE_OUTPUT 0x200000 + struct fb_info { int node; int flags; @@ -854,15 +957,32 @@ struct fb_info { #define FBINFO_STATE_SUSPENDED 1 u32 state; /* Hardware state i.e suspend */ void *fbcon_par; /* fbcon use-only private area */ + + struct fb_image bgdecor; + /* From here on everything is device dependent */ void *par; /* we need the PCI or similiar aperture base/size not smem_start/size as smem_start may just be an object allocated inside the aperture so may not actually overlap */ - resource_size_t aperture_base; - resource_size_t aperture_size; + struct apertures_struct { + unsigned int count; + struct aperture { + resource_size_t base; + resource_size_t size; + } ranges[0]; + } *apertures; }; +static inline struct apertures_struct *alloc_apertures(unsigned int max_num) { + struct apertures_struct *a = kzalloc(sizeof(struct apertures_struct) + + max_num * sizeof(struct aperture), GFP_KERNEL); + if (!a) + return NULL; + a->count = max_num; + return a; +} + #ifdef MODULE #define FBINFO_DEFAULT FBINFO_MODULE #else @@ -898,6 +1018,8 @@ struct fb_info { #define fb_writel sbus_writel #define fb_writeq sbus_writeq #define fb_memset sbus_memset_io +#define fb_memcpy_fromfb sbus_memcpy_fromio +#define fb_memcpy_tofb sbus_memcpy_toio #elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) @@ -910,6 +1032,8 @@ struct fb_info { #define fb_writel __raw_writel #define fb_writeq __raw_writeq #define fb_memset memset_io +#define fb_memcpy_fromfb memcpy_fromio +#define fb_memcpy_tofb memcpy_toio #else @@ -922,6 +1046,8 @@ struct fb_info { #define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b)) #define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b)) #define fb_memset memset +#define fb_memcpy_fromfb memcpy +#define fb_memcpy_tofb memcpy #endif @@ -955,6 +1081,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); +extern void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); extern int fb_show_logo(struct fb_info *fb_info, int rotate); extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size); @@ -1052,6 +1180,8 @@ extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var); extern const unsigned char *fb_firmware_edid(struct device *device); extern void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs); +extern void fb_edid_add_monspecs(unsigned char *edid, + struct fb_monspecs *specs); extern void fb_destroy_modedb(struct fb_videomode *modedb); extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb); extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter); @@ -1082,6 +1212,7 @@ extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs /* drivers/video/fbcmap.c */ extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp); +extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags); extern void fb_dealloc_cmap(struct fb_cmap *cmap); extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to); extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to); diff --git a/include/linux/msm_audio_1550.h b/include/linux/msm_audio_1550.h new file mode 100644 index 00000000..35203c94 --- /dev/null +++ b/include/linux/msm_audio_1550.h @@ -0,0 +1,209 @@ +/* include/linux/msm_audio.h + * + * Copyright (C) 2008 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#ifndef __LINUX_MSM_AUDIO_H +#define __LINUX_MSM_AUDIO_H + +#include +#include +#include + +/* PCM Audio */ + +#define AUDIO_IOCTL_MAGIC 'a' + +#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned) +#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned) +#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned) +#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned) +#define AUDIO_PLAY_DTMF _IOW(AUDIO_IOCTL_MAGIC, 19, unsigned) + +#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned) +#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned) +#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned) +#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned) +#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned) +#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned) +#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned) +#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned) +#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned) +#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned) +#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned) +#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned) +#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, unsigned) +#define AUDIO_ABORT_GET_EVENT _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned) +#define AUDIO_REGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned) +#define AUDIO_DEREGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 16, unsigned) +#define AUDIO_WAIT_ADSP_DONE _IOR(AUDIO_IOCTL_MAGIC, 16, unsigned) +#define AUDIO_ADSP_PAUSE _IOR(AUDIO_IOCTL_MAGIC, 17, unsigned) +#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, unsigned) +#define AUDIO_ADSP_RESUME _IOR(AUDIO_IOCTL_MAGIC, 18, unsigned) +#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, unsigned) +#define AUDIO_SET_INCALL _IOW(AUDIO_IOCTL_MAGIC, 19, \ + struct msm_voicerec_mode) +#define AUDIO_GET_NUM_SND_DEVICE _IOR(AUDIO_IOCTL_MAGIC, 20, unsigned) +#define AUDIO_GET_AMRNB_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 21, unsigned) +#define AUDIO_GET_SND_DEVICES _IOWR(AUDIO_IOCTL_MAGIC, 21, \ + struct msm_snd_device_list) +#define AUDIO_SET_AMRNB_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 22, unsigned) +#define AUDIO_ENABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 22, unsigned) +#define AUDIO_DISABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 23, unsigned) +#define AUDIO_ROUTE_STREAM _IOW(AUDIO_IOCTL_MAGIC, 24, \ + struct msm_audio_route_config) +#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned) +#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned) +#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned) +#define AUDIO_SET_MUTE _IOW(AUDIO_IOCTL_MAGIC, 33, unsigned) +#define AUDIO_UPDATE_ACDB _IOW(AUDIO_IOCTL_MAGIC, 34, unsigned) +#define AUDIO_START_VOICE _IOW(AUDIO_IOCTL_MAGIC, 35, unsigned) +#define AUDIO_STOP_VOICE _IOW(AUDIO_IOCTL_MAGIC, 36, unsigned) +#define AUDIO_START_FM _IOW(AUDIO_IOCTL_MAGIC, 37, unsigned) +#define AUDIO_STOP_FM _IOW(AUDIO_IOCTL_MAGIC, 38, unsigned) +#define AUDIO_REINIT_ACDB _IOW(AUDIO_IOCTL_MAGIC, 39, unsigned) +#define AUDIO_ENABLE_AUXPGA_LOOPBACK _IOW(AUDIO_IOCTL_MAGIC, 40, unsigned) +#define AUDIO_OUTPORT_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 40, \ + unsigned short) +#define AUDIO_SET_AUXPGA_GAIN _IOW(AUDIO_IOCTL_MAGIC, 41, unsigned) +#define AUDIO_SET_ERR_THRESHOLD_VALUE _IOW(AUDIO_IOCTL_MAGIC, 41, \ + unsigned short) +#define AUDIO_SET_RX_MUTE _IOW(AUDIO_IOCTL_MAGIC, 42, unsigned) +#define AUDIO_GET_BITSTREAM_ERROR_INFO _IOR(AUDIO_IOCTL_MAGIC, 42, \ + struct msm_audio_bitstream_error_info) + +/* Qualcomm extensions */ +#define AUDIO_SET_STREAM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 80, \ + struct msm_audio_stream_config) +#define AUDIO_GET_STREAM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 81, \ + struct msm_audio_stream_config) +#define AUDIO_GET_SESSION_ID _IOR(AUDIO_IOCTL_MAGIC, 82, \ + unsigned short) +#define AUDIO_GET_STREAM_INFO _IOR(AUDIO_IOCTL_MAGIC, 83, \ + struct msm_audio_bitstream_info) +#define AUDIO_SET_PAN _IOW(AUDIO_IOCTL_MAGIC, 84, unsigned) +#define AUDIO_SET_QCONCERT_PLUS _IOW(AUDIO_IOCTL_MAGIC, 85, unsigned) +#define AUDIO_SET_MBADRC _IOW(AUDIO_IOCTL_MAGIC, 86, unsigned) +#define AUDIO_SET_VOLUME_PATH _IOW(AUDIO_IOCTL_MAGIC, 87, \ + struct msm_vol_info) +#define AUDIO_SET_MAX_VOL_ALL _IOW(AUDIO_IOCTL_MAGIC, 88, unsigned) +#define AUDIO_GET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 93, \ + struct msm_audio_buf_cfg) +#define AUDIO_SET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 94, \ + struct msm_audio_buf_cfg) +#define AUDIO_SET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 95, \ + struct msm_acdb_cmd_device) +#define AUDIO_GET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 96, \ + struct msm_acdb_cmd_device) + +#define AUDIO_MAX_COMMON_IOCTL_NUM 100 + +struct msm_audio_config { + uint32_t buffer_size; + uint32_t buffer_count; + uint32_t channel_count; + uint32_t sample_rate; + uint32_t type; + uint32_t unused[3]; +}; + +struct msm_audio_stats { + uint32_t byte_count; + uint32_t sample_count; + uint32_t unused[2]; +}; + +struct msm_mute_info { + uint32_t mute; + uint32_t path; +}; + +#define AAC_OBJECT_ER_LC 17 +#define AAC_OBJECT_ER_LTP 19 +#define AAC_OBJECT_ER_SCALABLE 20 +#define AAC_OBJECT_BSAC 22 +#define AAC_OBJECT_ER_LD 23 + +struct aac_format { + uint16_t sample_rate; + uint16_t channel_config; + uint16_t block_formats; + uint16_t audio_object_type; + uint16_t ep_config; + uint16_t aac_section_data_resilience_flag; + uint16_t aac_scalefactor_data_resilience_flag; + uint16_t aac_spectral_data_resilience_flag; + uint16_t sbr_on_flag; + uint16_t sbr_ps_on_flag; + uint32_t bit_rate; +}; + +struct msm_audio_stream_config { + uint32_t buffer_size; + uint32_t buffer_count; +}; + +/* Audio routing */ + +#define SND_IOCTL_MAGIC 's' + +#define SND_MUTE_UNMUTED 0 +#define SND_MUTE_MUTED 1 + +struct msm_voicerec_mode { + uint32_t rec_mode; +}; + +struct msm_snd_device_config { + uint32_t device; + uint32_t ear_mute; + uint32_t mic_mute; +}; + +#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *) + +#define SND_METHOD_VOICE 0 + +struct msm_snd_volume_config { + uint32_t device; + uint32_t method; + uint32_t volume; +}; + +#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *) + +/* Returns the number of SND endpoints supported. */ + +#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *) + +struct msm_snd_endpoint { + int id; /* input and output */ + char name[64]; /* output only */ +}; + +/* Takes an index between 0 and one less than the number returned by + * SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a + * SND endpoint. On input, the .id field contains the number of the + * endpoint, and on exit it contains the SND index, while .name contains + * the description of the endpoint. + */ + +#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *) + +struct msm_audio_pcm_config { + uint32_t pcm_feedback; /* 0 - disable > 0 - enable */ + uint32_t buffer_count; /* Number of buffers to allocate */ + uint32_t buffer_size; /* Size of buffer for capturing of + PCM samples */ +}; +#endif diff --git a/include/linux/msm_audio_aac.h b/include/linux/msm_audio_aac.h new file mode 100644 index 00000000..b2eea5e5 --- /dev/null +++ b/include/linux/msm_audio_aac.h @@ -0,0 +1,91 @@ +/* arch/arm/mach-msm/include/mach/msm_audio_aac.h + * + * Copyright (c) 2009, Code Aurora Forum. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License + * along with this program; if not, you can find it at http://www.fsf.org. + * + */ + +#ifndef __MSM_AUDIO_AAC_H +#define __MSM_AUDIO_AAC_H + +#include + +#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned) +#define AUDIO_GET_AAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned) + +#define AUDIO_SET_AAC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config) + +#define AUDIO_GET_AAC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \ + (AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config) + +#define AUDIO_AAC_FORMAT_ADTS -1 +#define AUDIO_AAC_FORMAT_RAW 0x0000 +#define AUDIO_AAC_FORMAT_PSUEDO_RAW 0x0001 +#define AUDIO_AAC_FORMAT_LOAS 0x0002 +#define AUDIO_AAC_FORMAT_ADIF 0x0003 + + +#define AUDIO_AAC_OBJECT_LC 0x0002 +#define AUDIO_AAC_OBJECT_LTP 0x0004 +#define AUDIO_AAC_OBJECT_ERLC 0x0011 +#define AUDIO_AAC_OBJECT_BSAC 0x0016 + +#define AUDIO_AAC_SEC_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SEC_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SCA_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SCA_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SPEC_DATA_RES_ON 0x0001 +#define AUDIO_AAC_SPEC_DATA_RES_OFF 0x0000 + +#define AUDIO_AAC_SBR_ON_FLAG_ON 0x0001 +#define AUDIO_AAC_SBR_ON_FLAG_OFF 0x0000 + +#define AUDIO_AAC_SBR_PS_ON_FLAG_ON 0x0001 +#define AUDIO_AAC_SBR_PS_ON_FLAG_OFF 0x0000 + +/* Primary channel on both left and right channels */ +#define AUDIO_AAC_DUAL_MONO_PL_PR 0 +/* Secondary channel on both left and right channels */ +#define AUDIO_AAC_DUAL_MONO_SL_SR 1 +/* Primary channel on right channel and 2nd on left channel */ +#define AUDIO_AAC_DUAL_MONO_SL_PR 2 +/* 2nd channel on right channel and primary on left channel */ +#define AUDIO_AAC_DUAL_MONO_PL_SR 3 + +struct msm_audio_aac_config { + signed short format; + unsigned short audio_object; + unsigned short ep_config; /* 0 ~ 3 useful only obj = ERLC */ + unsigned short aac_section_data_resilience_flag; + unsigned short aac_scalefactor_data_resilience_flag; + unsigned short aac_spectral_data_resilience_flag; + unsigned short sbr_on_flag; + unsigned short sbr_ps_on_flag; + unsigned short dual_mono_mode; + unsigned short channel_configuration; +}; + +struct msm_audio_aac_enc_config { + uint32_t channels; + uint32_t sample_rate; + uint32_t bit_rate; + uint32_t stream_format; +}; + +#endif /* __MSM_AUDIO_AAC_H */ diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h index a5a75638..a933facc 100644 --- a/include/linux/msm_mdp.h +++ b/include/linux/msm_mdp.h @@ -19,36 +19,21 @@ #define MSMFB_IOCTL_MAGIC 'm' #define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int) #define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int) -#ifdef CONFIG_MSM_MDP40 -#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \ - struct mdp_overlay) -#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int) -#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \ - struct msmfb_overlay_data) -#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \ - struct mdp_overlay) -#endif enum { - MDP_RGB_565, // RGB 565 planer - MDP_XRGB_8888, // RGB 888 padded - MDP_Y_CBCR_H2V2, // Y and CbCr, pseudo planer w/ Cb is in MSB - MDP_ARGB_8888, // ARGB 888 - MDP_RGB_888, // RGB 888 planer - MDP_Y_CRCB_H2V2, // Y and CrCb, pseudo planer w/ Cr is in MSB - MDP_YCRYCB_H2V1, // YCrYCb interleave - MDP_Y_CRCB_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB - MDP_Y_CBCR_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB - MDP_RGBA_8888, // ARGB 888 - MDP_BGRA_8888, // ARGB 888 - MDP_RGBX_8888, // RGBX 888 - MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */ - MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */ - MDP_IMGTYPE_LIMIT, // Non valid image type after this enum - MDP_IMGTYPE2_START = 0x10000, - MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */ - MDP_FB_FORMAT, /* framebuffer format */ - MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */ + MDP_RGB_565, /* RGB 565 planar */ + MDP_XRGB_8888, /* RGB 888 padded */ + MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planar w/ Cb is in MSB */ + MDP_ARGB_8888, /* ARGB 888 */ + MDP_RGB_888, /* RGB 888 planar */ + MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planar w/ Cr is in MSB */ + MDP_YCRYCB_H2V1, /* YCrYCb interleave */ + MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ + MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */ + MDP_RGBA_8888, /* ARGB 888 */ + MDP_BGRA_8888, /* ABGR 888 */ + MDP_RGBX_8888, /* RGBX 888 */ + MDP_IMGTYPE_LIMIT /* Non valid image type after this enum */ }; enum { @@ -57,20 +42,23 @@ enum { }; /* flag values */ -#define MDP_ROT_NOP 0 -#define MDP_FLIP_LR 0x1 -#define MDP_FLIP_UD 0x2 -#define MDP_ROT_90 0x4 -#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) -#define MDP_ROT_MASK 0x7 -#define MDP_DITHER 0x8 -#define MDP_BLUR 0x10 +#define MDP_ROT_NOP 0 +#define MDP_FLIP_LR 0x1 +#define MDP_FLIP_UD 0x2 +#define MDP_ROT_90 0x4 +#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR) +#define MDP_ROT_MASK 0x7 +#define MDP_DITHER 0x8 +#define MDP_BLUR 0x10 #define MDP_BLEND_FG_PREMULT 0x20000 -#define MDP_DEINTERLACE 0x80000000 -#define MDP_SHARPENING 0x40000000 -#define MDP_TRANSP_NOP 0xffffffff -#define MDP_ALPHA_NOP 0xff + +#define MDP_TRANSP_NOP 0xffffffff +#define MDP_ALPHA_NOP 0xff + +/* drewis: added for android 4.0 */ +#define MDP_BLIT_NON_CACHED 0x01000000 +/* drewis: end */ struct mdp_rect { uint32_t x; @@ -95,7 +83,6 @@ struct mdp_blit_req { uint32_t alpha; uint32_t transp_mask; uint32_t flags; - int sharpening_strength; /* -127 <--> 127, default 64 */ }; struct mdp_blit_req_list { @@ -103,37 +90,4 @@ struct mdp_blit_req_list { struct mdp_blit_req req[]; }; -#ifdef CONFIG_MSM_MDP40 -struct msmfb_data { - uint32_t offset; - int memory_id; - int id; -}; - -#define MSMFB_NEW_REQUEST -1 - -struct msmfb_overlay_data { - uint32_t id; - struct msmfb_data data; -}; - -struct msmfb_img { - uint32_t width; - uint32_t height; - uint32_t format; -}; - -struct mdp_overlay { - struct msmfb_img src; - struct mdp_rect src_rect; - struct mdp_rect dst_rect; - uint32_t z_order; /* stage number */ - uint32_t is_fg; /* control alpha & transp */ - uint32_t alpha; - uint32_t transp_mask; - uint32_t flags; - uint32_t id; - uint32_t user_data[8]; -}; -#endif -#endif //_MSM_MDP_H_ +#endif /* _MSM_MDP_H_ */ From e8bd623aa0d4f67ab28142eb6a793553f958fe81 Mon Sep 17 00:00:00 2001 From: Shantanu Gupta Date: Thu, 3 May 2012 21:30:12 +0530 Subject: [PATCH 5/6] [MSM] revert qdsp backport, seems to break quite a lot of stuff, will fix it later. --- arch/arm/mach-msm/board-htcleo-audio.c | 1 - .../include/mach/msm_qdsp6_audio_1550.h | 10 +- arch/arm/mach-msm/qdsp6_1550/aac_in.c | 503 +++++------------- arch/arm/mach-msm/qdsp6_1550/audio_ctl.c | 29 +- arch/arm/mach-msm/qdsp6_1550/dal.c | 1 - arch/arm/mach-msm/qdsp6_1550/mp3.c | 1 - arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c | 1 - arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c | 3 +- arch/arm/mach-msm/qdsp6_1550/pcm_in.c | 1 - arch/arm/mach-msm/qdsp6_1550/pcm_out.c | 7 - arch/arm/mach-msm/qdsp6_1550/q6audio.c | 172 +++--- arch/arm/mach-msm/qdsp6_1550/qcelp_in.c | 1 - 12 files changed, 233 insertions(+), 497 deletions(-) diff --git a/arch/arm/mach-msm/board-htcleo-audio.c b/arch/arm/mach-msm/board-htcleo-audio.c index 1ee46c6d..3b2e66c7 100644 --- a/arch/arm/mach-msm/board-htcleo-audio.c +++ b/arch/arm/mach-msm/board-htcleo-audio.c @@ -24,7 +24,6 @@ #include #include #include -#include #include "board-htcleo.h" #include "devices.h" diff --git a/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h b/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h index fcbfbfcd..1f6df9a4 100644 --- a/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h +++ b/arch/arm/mach-msm/include/mach/msm_qdsp6_audio_1550.h @@ -19,14 +19,12 @@ #define AUDIO_FLAG_READ 0 #define AUDIO_FLAG_WRITE 1 -#define AUDIO_FLAG_INCALL_MIXED 2 struct audio_buffer { dma_addr_t phys; void *data; uint32_t size; uint32_t used; /* 1 = CPU is waiting for DSP to consume this buf */ - uint32_t actual_size; /* actual number of bytes read by DSP */ }; struct audio_client { @@ -81,10 +79,8 @@ struct audio_client *q6audio_open_mp3(uint32_t bufsz, uint32_t rate, struct audio_client *q6fm_open(void); -struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, - uint32_t channels, uint32_t bitrate, - uint32_t stream_format, uint32_t flags, - uint32_t acdb_id); +struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate, + uint32_t flags, void *data, uint32_t acdb_id); struct audio_client *q6audio_open_qcelp(uint32_t bufsz, uint32_t rate, void *data, uint32_t acdb_id); @@ -106,7 +102,7 @@ int q6audio_set_tx_mute(int mute); int q6audio_reinit_acdb(char* filename); int q6audio_update_acdb(uint32_t id_src, uint32_t id_dst); int q6audio_set_rx_volume(int level); -int q6audio_set_tx_volume(int mute); +int q6audio_set_tx_volume(int level); int q6audio_set_stream_volume(struct audio_client *ac, int vol); int q6audio_set_tx_dev_volume(int device_id, int level); int q6audio_get_tx_dev_volume(int device_id); diff --git a/arch/arm/mach-msm/qdsp6_1550/aac_in.c b/arch/arm/mach-msm/qdsp6_1550/aac_in.c index 23455666..9b9f1c46 100644 --- a/arch/arm/mach-msm/qdsp6_1550/aac_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/aac_in.c @@ -1,7 +1,7 @@ -/* +/* arch/arm/mach-msm/qdsp6/aac_in.c + * * Copyright (C) 2009 Google, Inc. * Copyright (C) 2009 HTC Corporation - * Copyright (c) 2010, Code Aurora Forum. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -12,9 +12,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - */ +*/ -#include #include #include #include @@ -22,449 +21,197 @@ #include #include #include -#include -#include -#include - -#include -#include +#include #include -#include -#define AAC_FC_BUFF_CNT 10 -#define AAC_READ_TIMEOUT 2000 -struct aac_fc_buff { - struct mutex lock; - int empty; - void *data; - int size; - int actual_size; -}; +#define BUFSZ (4096) +#define DMASZ (BUFSZ * 2) -struct aac_fc { - struct task_struct *task; - wait_queue_head_t fc_wq; - struct aac_fc_buff fc_buff[AAC_FC_BUFF_CNT]; - int buff_index; -}; -struct aac { - struct mutex lock; - struct msm_audio_aac_enc_config cfg; - struct msm_audio_stream_config str_cfg; - struct audio_client *audio_client; - struct msm_voicerec_mode voicerec_mode; - struct aac_fc *aac_fc; -}; +#if 0 +#define TRACE(x...) pr_info("Q6: "x) +#else +#define TRACE(x...) do{}while(0) +#endif -static int q6_aac_flowcontrol(void *data) +static DEFINE_MUTEX(aac_in_lock); +static int aac_in_opened = 0; +static struct aac_format *af; + +void audio_client_dump(struct audio_client *ac); + +static long aac_in_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - struct audio_client *ac; - struct audio_buffer *ab; - struct aac *aac = data; - int buff_index = 0; - int xfer = 0; - struct aac_fc *fc; - - - ac = aac->audio_client; - fc = aac->aac_fc; - if (!ac) { - pr_err("[%s:%s] audio_client is NULL\n", __MM_FILE__, __func__); - return 0; - } - - while (!kthread_should_stop()) { - ab = ac->buf + ac->cpu_buf; - if (ab->used) - wait_event(ac->wait, (ab->used == 0)); - pr_debug("[%s:%s] ab->data = %p, cpu_buf = %d\n", __MM_FILE__, - __func__, ab->data, ac->cpu_buf); - xfer = ab->actual_size; - - mutex_lock(&(fc->fc_buff[buff_index].lock)); - if (!fc->fc_buff[buff_index].empty) { - pr_err("[%s:%s] flow control buffer[%d] not read!\n", - __MM_FILE__, __func__, buff_index); - } - - if (fc->fc_buff[buff_index].size < xfer) { - pr_err("[%s:%s] buffer %d too small\n", __MM_FILE__, - __func__, buff_index); - memcpy(fc->fc_buff[buff_index].data, - ab->data, fc->fc_buff[buff_index].size); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = - fc->fc_buff[buff_index].size; - } else { - memcpy(fc->fc_buff[buff_index].data, ab->data, xfer); - fc->fc_buff[buff_index].empty = 0; - fc->fc_buff[buff_index].actual_size = xfer; - } - mutex_unlock(&(fc->fc_buff[buff_index].lock)); - /*wake up client, if any*/ - wake_up(&fc->fc_wq); - - buff_index++; - if (buff_index >= AAC_FC_BUFF_CNT) - buff_index = 0; - - ab->used = 1; - - q6audio_read(ac, ab); - ac->cpu_buf ^= 1; - } - - return 0; -} -static long q6_aac_in_ioctl(struct file *file, - unsigned int cmd, unsigned long arg) -{ - struct aac *aac = file->private_data; int rc = 0; - int i = 0; - struct aac_fc *fc; - int size = 0; - mutex_lock(&aac->lock); switch (cmd) { case AUDIO_SET_VOLUME: break; - case AUDIO_GET_STATS: - { + case AUDIO_GET_STATS: { struct msm_audio_stats stats; - pr_debug("[%s:%s] GET_STATS\n", __MM_FILE__, __func__); memset(&stats, 0, sizeof(stats)); - if (copy_to_user((void *) arg, &stats, sizeof(stats))) + if (copy_to_user((void*) arg, &stats, sizeof(stats))) return -EFAULT; return 0; } - case AUDIO_START: - { + case AUDIO_START: { uint32_t acdb_id; - pr_debug("[%s:%s] AUDIO_START\n", __MM_FILE__, __func__); + rc = 0; + if (arg == 0) { acdb_id = 0; - } else { - if (copy_from_user(&acdb_id, (void *) arg, - sizeof(acdb_id))) { - rc = -EFAULT; - break; - } - } - if (aac->audio_client) { - rc = -EBUSY; - pr_err("[%s:%s] active session already existing\n", - __MM_FILE__, __func__); + } else if (copy_from_user(&acdb_id, + (void*) arg, sizeof(acdb_id))) { + rc = -EFAULT; break; + } + + mutex_lock(&aac_in_lock); + if (file->private_data) { + rc = -EBUSY; } else { - aac->audio_client = q6audio_open_aac( - aac->str_cfg.buffer_size, - aac->cfg.sample_rate, - aac->cfg.channels, - aac->cfg.bit_rate, - aac->cfg.stream_format, - aac->voicerec_mode.rec_mode, acdb_id); - - if (aac->audio_client < 0) { - pr_err("[%s:%s] aac open session failed\n", - __MM_FILE__, __func__); + file->private_data = q6audio_open_aac( + BUFSZ, 48000, AUDIO_FLAG_READ, af, acdb_id); + if (!file->private_data) rc = -ENOMEM; - break; - } - } - - /*allocate flow control buffers*/ - fc = aac->aac_fc; - size = ((aac->str_cfg.buffer_size < 1543) ? 1543 : - aac->str_cfg.buffer_size); - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - mutex_init(&(fc->fc_buff[i].lock)); - fc->fc_buff[i].empty = 1; - fc->fc_buff[i].data = kmalloc(size, GFP_KERNEL); - if (fc->fc_buff[i].data == NULL) { - pr_err("[%s:%s] No memory for FC buffers\n", - __MM_FILE__, __func__); - rc = -ENOMEM; - goto fc_fail; - } - fc->fc_buff[i].size = size; - fc->fc_buff[i].actual_size = 0; - } - - /*create flow control thread*/ - fc->task = kthread_run(q6_aac_flowcontrol, - aac, "aac_flowcontrol"); - if (IS_ERR(fc->task)) { - rc = PTR_ERR(fc->task); - pr_err("[%s:%s] error creating flow control thread\n", - __MM_FILE__, __func__); - goto fc_fail; - } - break; -fc_fail: - /*free flow control buffers*/ - --i; - for (; i >= 0; i--) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; } + mutex_unlock(&aac_in_lock); break; } case AUDIO_STOP: - pr_debug("[%s:%s] AUDIO_STOP\n", __MM_FILE__, __func__); break; case AUDIO_FLUSH: break; - case AUDIO_SET_INCALL: { - pr_debug("[%s:%s] SET_INCALL\n", __MM_FILE__, __func__); - if (copy_from_user(&aac->voicerec_mode, - (void *)arg, sizeof(struct msm_voicerec_mode))) + case AUDIO_SET_CONFIG: { + struct msm_audio_config config; + if (copy_from_user(&config, (void*) arg, sizeof(config))) { + rc = -EFAULT; + break; + } + if (config.sample_rate != 48000) + pr_info("only 48KHz AAC encode supported\n"); + af->channel_config = config.channel_count; + break; + } + case AUDIO_GET_CONFIG: { + struct msm_audio_config config; + config.buffer_size = BUFSZ; + config.buffer_count = 2; + config.sample_rate = 48000; + config.channel_count = af->channel_config; + config.unused[0] = 0; + config.unused[1] = 0; + config.unused[2] = 0; + if (copy_to_user((void*) arg, &config, sizeof(config))) { rc = -EFAULT; - - if (aac->voicerec_mode.rec_mode != AUDIO_FLAG_READ - && aac->voicerec_mode.rec_mode != - AUDIO_FLAG_INCALL_MIXED) { - aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - pr_err("[%s:%s] Invalid rec_mode\n", __MM_FILE__, - __func__); - rc = -EINVAL; } break; } - case AUDIO_GET_STREAM_CONFIG: - if (copy_to_user((void *)arg, &aac->str_cfg, - sizeof(struct msm_audio_stream_config))) - rc = -EFAULT; - pr_debug("[%s:%s] GET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, aac->str_cfg.buffer_size, - aac->str_cfg.buffer_count); - break; - case AUDIO_SET_STREAM_CONFIG: - if (copy_from_user(&aac->str_cfg, (void *)arg, - sizeof(struct msm_audio_stream_config))) { - rc = -EFAULT; - break; - } - pr_debug("[%s:%s] SET_STREAM_CONFIG: buffsz=%d, buffcnt=%d\n", - __MM_FILE__, __func__, aac->str_cfg.buffer_size, - aac->str_cfg.buffer_count); - if (aac->str_cfg.buffer_size < 1543) { - pr_err("[%s:%s] Buffer size too small\n", __MM_FILE__, - __func__); - rc = -EINVAL; - break; - } - if (aac->str_cfg.buffer_count != 2) - pr_info("[%s:%s] Buffer count set to 2\n", __MM_FILE__, - __func__); - - break; - case AUDIO_SET_AAC_ENC_CONFIG: - if (copy_from_user(&aac->cfg, (void *) arg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] SET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", - __MM_FILE__, __func__, aac->cfg.channels, - aac->cfg.sample_rate); - if (aac->cfg.channels < 1 || aac->cfg.channels > 2) { - pr_err("[%s:%s]invalid number of channels\n", - __MM_FILE__, __func__); - rc = -EINVAL; - } - if (aac->cfg.sample_rate != 48000) { - pr_err("[%s:%s] only 48KHz is supported\n", - __MM_FILE__, __func__); - rc = -EINVAL; - } - if (aac->cfg.stream_format != AUDIO_AAC_FORMAT_RAW && - aac->cfg.stream_format != AUDIO_AAC_FORMAT_ADTS) { - pr_err("[%s:%s] unsupported AAC format\n", __MM_FILE__, - __func__); - rc = -EINVAL; - } - break; - case AUDIO_GET_AAC_ENC_CONFIG: - if (copy_to_user((void *) arg, &aac->cfg, - sizeof(struct msm_audio_aac_enc_config))) { - rc = -EFAULT; - } - pr_debug("[%s:%s] GET_AAC_ENC_CONFIG: channels=%d, rate=%d\n", - __MM_FILE__, __func__, aac->cfg.channels, - aac->cfg.sample_rate); - break; default: rc = -EINVAL; } - - mutex_unlock(&aac->lock); - pr_debug("[%s:%s] rc = %d\n", __MM_FILE__, __func__, rc); return rc; } -static int q6_aac_in_open(struct inode *inode, struct file *file) +static int aac_in_open(struct inode *inode, struct file *file) { + int rc; - struct aac *aac; - struct aac_fc *fc; - int i; - pr_info("[%s:%s] open\n", __MM_FILE__, __func__); - aac = kmalloc(sizeof(struct aac), GFP_KERNEL); - if (aac == NULL) { - pr_err("[%s:%s] Could not allocate memory for aac driver\n", - __MM_FILE__, __func__); - return -ENOMEM; - } + pr_info("aac_in: open\n"); + mutex_lock(&aac_in_lock); + if (aac_in_opened) { + pr_err("aac_in: busy\n"); + rc = -EBUSY; + } else { + af = kzalloc(sizeof(*af), GFP_KERNEL); + memset(af, 0, sizeof(struct aac_format)); + af->sample_rate = 3; /* 48000 */ + af->channel_config = 1; + af->block_formats = AUDIO_AAC_FORMAT_ADTS; + af->audio_object_type = 2; /* CAD to ADSP format */ + af->bit_rate = 192000; - mutex_init(&aac->lock); - file->private_data = aac; - aac->audio_client = NULL; - aac->str_cfg.buffer_size = 1543; - aac->str_cfg.buffer_count = 2; - aac->cfg.channels = 1; - aac->cfg.bit_rate = 192000; - aac->cfg.stream_format = AUDIO_AAC_FORMAT_ADTS; - aac->cfg.sample_rate = 48000; - aac->voicerec_mode.rec_mode = AUDIO_FLAG_READ; - - aac->aac_fc = kmalloc(sizeof(struct aac_fc), GFP_KERNEL); - if (aac->aac_fc == NULL) { - pr_err("[%s:%s] Could not allocate memory for aac_fc\n", - __MM_FILE__, __func__); - kfree(aac); - return -ENOMEM; + aac_in_opened = 1; + rc = 0; } - fc = aac->aac_fc; - fc->task = NULL; - fc->buff_index = 0; - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - fc->fc_buff[i].data = NULL; - fc->fc_buff[i].size = 0; - fc->fc_buff[i].actual_size = 0; - } - /*initialize wait queue head*/ - init_waitqueue_head(&fc->fc_wq); - return 0; + mutex_unlock(&aac_in_lock); + return rc; } -static ssize_t q6_aac_in_read(struct file *file, char __user *buf, - size_t count, loff_t *pos) +static ssize_t aac_in_read(struct file *file, char __user *buf, + size_t count, loff_t *pos) { struct audio_client *ac; + struct audio_buffer *ab; const char __user *start = buf; - struct aac *aac = file->private_data; - struct aac_fc *fc; - int xfer = 0; - int res = 0; - - pr_debug("[%s:%s] count = %d\n", __MM_FILE__, __func__, count); - mutex_lock(&aac->lock); - ac = aac->audio_client; + int xfer, res = 0; + mutex_lock(&aac_in_lock); + ac = file->private_data; if (!ac) { res = -ENODEV; goto fail; } - fc = aac->aac_fc; + while (count > 0) { + ab = ac->buf + ac->cpu_buf; - /*wait for buffer to full*/ - if (fc->fc_buff[fc->buff_index].empty != 0) { - res = wait_event_interruptible_timeout(fc->fc_wq, - (fc->fc_buff[fc->buff_index].empty == 0), - msecs_to_jiffies(AAC_READ_TIMEOUT)); + if (ab->used) + if (!wait_event_timeout(ac->wait, (ab->used == 0), 5*HZ)) { + audio_client_dump(ac); + pr_err("aac_read: timeout. dsp dead?\n"); + BUG(); + } - pr_debug("[%s:%s] buff_index = %d\n", __MM_FILE__, - __func__, fc->buff_index); - if (res == 0) { - pr_err("[%s:%s] Timeout!\n", __MM_FILE__, __func__); - res = -ETIMEDOUT; - goto fail; - } else if (res < 0) { - pr_err("[%s:%s] Returning on Interrupt\n", __MM_FILE__, - __func__); + xfer = count; + if (xfer > ab->size) + xfer = ab->size; + + if (copy_to_user(buf, ab->data, xfer)) { + res = -EFAULT; goto fail; } + + buf += xfer; + count -= xfer; + + ab->used = 1; + q6audio_read(ac, ab); + ac->cpu_buf ^= 1; } - /*lock the buffer*/ - mutex_lock(&(fc->fc_buff[fc->buff_index].lock)); - xfer = fc->fc_buff[fc->buff_index].actual_size; - - if (xfer > count) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] read failed! byte count too small\n", - __MM_FILE__, __func__); - res = -EINVAL; - goto fail; - } - - if (copy_to_user(buf, fc->fc_buff[fc->buff_index].data, xfer)) { - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - pr_err("[%s:%s] copy_to_user failed at index %d\n", - __MM_FILE__, __func__, fc->buff_index); - res = -EFAULT; - goto fail; - } - - buf += xfer; - - fc->fc_buff[fc->buff_index].empty = 1; - fc->fc_buff[fc->buff_index].actual_size = 0; - - mutex_unlock(&(fc->fc_buff[fc->buff_index].lock)); - ++(fc->buff_index); - if (fc->buff_index >= AAC_FC_BUFF_CNT) - fc->buff_index = 0; - - res = buf - start; fail: - mutex_unlock(&aac->lock); - + res = buf - start; + mutex_unlock(&aac_in_lock); return res; } -static int q6_aac_in_release(struct inode *inode, struct file *file) +static int aac_in_release(struct inode *inode, struct file *file) { int rc = 0; - struct aac *aac = file->private_data; - int i = 0; - struct aac_fc *fc; - - mutex_lock(&aac->lock); - fc = aac->aac_fc; - kthread_stop(fc->task); - fc->task = NULL; - - /*free flow control buffers*/ - for (i = 0; i < AAC_FC_BUFF_CNT; ++i) { - kfree(fc->fc_buff[i].data); - fc->fc_buff[i].data = NULL; - } - kfree(fc); - if (aac->audio_client) - rc = q6audio_close(aac->audio_client); - mutex_unlock(&aac->lock); - kfree(aac); - pr_info("[%s:%s] release\n", __MM_FILE__, __func__); + pr_info("aac_in: release\n"); + mutex_lock(&aac_in_lock); + if (file->private_data) + rc = q6audio_close(file->private_data); + kfree(af); + aac_in_opened = 0; + mutex_unlock(&aac_in_lock); return rc; } -static const struct file_operations q6_aac_in_fops = { - .owner = THIS_MODULE, - .open = q6_aac_in_open, - .read = q6_aac_in_read, - .release = q6_aac_in_release, - .unlocked_ioctl = q6_aac_in_ioctl, +static struct file_operations aac_in_fops = { + .owner = THIS_MODULE, + .open = aac_in_open, + .read = aac_in_read, + .release = aac_in_release, + .unlocked_ioctl = aac_in_ioctl, }; -struct miscdevice q6_aac_in_misc = { - .minor = MISC_DYNAMIC_MINOR, - .name = "msm_aac_in", - .fops = &q6_aac_in_fops, +struct miscdevice aac_in_misc = { + .minor = MISC_DYNAMIC_MINOR, + .name = "msm_aac_in", + .fops = &aac_in_fops, }; -static int __init q6_aac_in_init(void) -{ - return misc_register(&q6_aac_in_misc); +static int __init aac_in_init(void) { + return misc_register(&aac_in_misc); } -device_initcall(q6_aac_in_init); +device_initcall(aac_in_init); diff --git a/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c b/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c index e37296a4..eaf5a942 100644 --- a/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c +++ b/arch/arm/mach-msm/qdsp6_1550/audio_ctl.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include @@ -133,7 +133,8 @@ static int q6_open(struct inode *inode, struct file *file) return 0; } -static long q6_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +static int q6_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { int rc; uint32_t n; @@ -146,40 +147,28 @@ static long q6_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case AUDIO_SWITCH_DEVICE: rc = copy_from_user(&id, (void *)arg, sizeof(id)); AUDIO_INFO("SWITCH DEVICE %d, acdb %d\n", id[0], id[1]); - if (rc) { - pr_err("%s: bad user address\n", __func__); - rc = -EFAULT; - } else + if (!rc) rc = q6audio_do_routing(id[0], id[1]); break; case AUDIO_SET_VOLUME: rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (rc) { - pr_err("%s: bad user address\n", __func__); - rc = -EFAULT; - } else + if (!rc) rc = q6audio_set_rx_volume(n); break; case AUDIO_SET_MUTE: rc = copy_from_user(&n, (void *)arg, sizeof(n)); - if (rc) { - pr_err("%s: bad user address\n", __func__); - rc = -EFAULT; - } else + if (!rc) rc = q6audio_set_tx_mute(n); break; case AUDIO_UPDATE_ACDB: rc = copy_from_user(&id, (void *)arg, sizeof(id)); - if (rc) { - pr_err("%s: bad user address\n", __func__); - rc = -EFAULT; - } else + if (!rc) rc = q6audio_update_acdb(id[0], id[1]); break; case AUDIO_START_VOICE: - if (arg == 0) + if (arg == 0) { id[0] = id[1] = 0; - else if (copy_from_user(&id, (void*) arg, sizeof(id))) { + } else if (copy_from_user(&id, (void*) arg, sizeof(id))) { pr_info("voice: copy acdb_id from user failed\n"); rc = -EFAULT; break; diff --git a/arch/arm/mach-msm/qdsp6_1550/dal.c b/arch/arm/mach-msm/qdsp6_1550/dal.c index f0374dfc..d05ccfb0 100644 --- a/arch/arm/mach-msm/qdsp6_1550/dal.c +++ b/arch/arm/mach-msm/qdsp6_1550/dal.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/mp3.c b/arch/arm/mach-msm/qdsp6_1550/mp3.c index 6b402c27..c04fc5d1 100644 --- a/arch/arm/mach-msm/qdsp6_1550/mp3.c +++ b/arch/arm/mach-msm/qdsp6_1550/mp3.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c b/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c index 2f525c8c..69ce1804 100644 --- a/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c +++ b/arch/arm/mach-msm/qdsp6_1550/msm_q6vdec.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c b/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c index 269b0a41..f32f2825 100644 --- a/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c +++ b/arch/arm/mach-msm/qdsp6_1550/msm_q6venc.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include @@ -359,7 +358,7 @@ static int q6_encode(struct q6venc_dev *q6venc, struct encode_param *enc_param) { struct q6_encode_param *q6_param = &enc_param->q6_encode_param; struct file *file; - struct buf_info *buf = 0; + struct buf_info *buf; int i; int ret; int rlc_buf_index; diff --git a/arch/arm/mach-msm/qdsp6_1550/pcm_in.c b/arch/arm/mach-msm/qdsp6_1550/pcm_in.c index 36abf17b..ad84f53f 100644 --- a/arch/arm/mach-msm/qdsp6_1550/pcm_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/pcm_in.c @@ -14,7 +14,6 @@ * */ -#include #include #include #include diff --git a/arch/arm/mach-msm/qdsp6_1550/pcm_out.c b/arch/arm/mach-msm/qdsp6_1550/pcm_out.c index eb8dae95..b3fbc8e6 100644 --- a/arch/arm/mach-msm/qdsp6_1550/pcm_out.c +++ b/arch/arm/mach-msm/qdsp6_1550/pcm_out.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -65,12 +64,6 @@ static long pcm_ioctl(struct file *file, unsigned int cmd, unsigned long arg) switch (cmd) { case AUDIO_SET_VOLUME: { int vol; - if (!pcm->ac) { - pr_err("%s: cannot set volume before AUDIO_START!\n", - __func__); - rc = -EINVAL; - break; - } if (copy_from_user(&vol, (void*) arg, sizeof(vol))) { rc = -EFAULT; break; diff --git a/arch/arm/mach-msm/qdsp6_1550/q6audio.c b/arch/arm/mach-msm/qdsp6_1550/q6audio.c index 0c8b2d30..8113ca19 100644 --- a/arch/arm/mach-msm/qdsp6_1550/q6audio.c +++ b/arch/arm/mach-msm/qdsp6_1550/q6audio.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -33,12 +32,11 @@ #include "dal_acdb.h" #include "dal_adie.h" #include -#include +#include #include #include #include -#include #include "q6audio_devices.h" #include "../dex_comm.h" @@ -174,7 +172,7 @@ static struct audio_client * audio_test(void); static void callback(void *data, int len, void *cookie); static int audio_init(struct audio_client *ac); static int audio_info(struct audio_client *ac); -static int q6audio_init_rx_volumes(void); +static int q6audio_init_rx_volumes(); static struct wake_lock wakelock; static struct wake_lock idlelock; @@ -217,7 +215,6 @@ static char acdb_file[64] = "default.acdb"; static uint32_t tx_acdb = 0; static uint32_t rx_acdb = 0; static int acdb_use_rpc = 0; -static int acdb_use_map = 0; ///////////////////////////////////////////////////////////////////////////////// // helper functions for device parameters @@ -702,18 +699,10 @@ static int audio_mp3_open(struct audio_client *ac, uint32_t bufsz, return ac->open_status; } -/* - * ported code for audio_aac_open from Code Aurora in order to work - * with new aac code from Code Aurora - * by marc1706 - */ -static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, - uint32_t sample_rate, uint32_t channels, - uint32_t bit_rate, uint32_t flags, - uint32_t stream_format) +static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, void *data) { int r; - int audio_object_type; + struct aac_format *af = data; struct adsp_open_command rpc; uint32_t *aac_type; int idx = 0; // sizeof(uint32_t); @@ -734,33 +723,77 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, rpc.pblock = params_phys; aac_type = (uint32_t *)(fmt->data); - switch (stream_format) + switch (af->block_formats) { - case AUDIO_AAC_FORMAT_ADTS: - /* AAC Encoder expect MPEG4_ADTS media type */ - *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; - break; - case AUDIO_AAC_FORMAT_RAW: - /* for ADIF recording */ - *aac_type = ADSP_AUDIO_AAC_RAW; - break; + case 0xffff: + if (ac->flags & AUDIO_FLAG_WRITE) + *aac_type = ADSP_AUDIO_AAC_ADTS; + else + *aac_type = ADSP_AUDIO_AAC_MPEG4_ADTS; + break; + case 0: + if (ac->flags & AUDIO_FLAG_WRITE) + *aac_type = ADSP_AUDIO_AAC_ADIF; + else + *aac_type = ADSP_AUDIO_AAC_RAW; + break; + case 1: + *aac_type = ADSP_AUDIO_AAC_RAW; + break; + case 2: + *aac_type = ADSP_AUDIO_AAC_LOAS; + break; + case 3: + *aac_type = ADSP_AUDIO_AAC_FRAMED_RAW; + break; + case 4: + *aac_type = ADSP_AUDIO_AAC_RAW; + break; default: - pr_err("unsupported AAC type %d\n", stream_format); + pr_err("unsupported AAC type %d\n", af->block_formats); mutex_unlock(&open_mem_lock); return -EINVAL; } - - /* AAC OBJECT LC */ - audio_object_type = 2; AUDIO_INFO("aac_open: type %x, obj %d, idx %d\n", - *aac_type, audio_object_type, idx); + *aac_type, af->audio_object_type, idx); + fmt->data[idx++] = (u8)(((af->audio_object_type & 0x1F) << 3) | + ((af->sample_rate >> 1) & 0x7)); + fmt->data[idx] = (u8)(((af->sample_rate & 0x1) << 7) | + ((af->channel_config & 0x7) << 3)); - fmt->data[idx++] = (u8)(((audio_object_type & 0x1F) << 3) | - ((sample_rate >> 1) & 0x7)); - fmt->data[idx] = (u8)(((sample_rate & 0x1) << 7) | - ((channels & 0x7) << 3)); + switch (af->audio_object_type) { + case AAC_OBJECT_ER_LC: + case AAC_OBJECT_ER_LTP: + case AAC_OBJECT_ER_LD: + /* extension flag */ + fmt->data[idx++] |= 0x1; + fmt->data[idx] = (u8)( + ((af->aac_section_data_resilience_flag & 0x1) << 7) | + ((af->aac_scalefactor_data_resilience_flag & 0x1) << 6) | + ((af->aac_spectral_data_resilience_flag & 0x1) << 5) | + ((af->ep_config & 0x3) << 2)); + break; + case AAC_OBJECT_ER_SCALABLE: + fmt->data[idx++] |= 0x1; + /* extension flag */ + fmt->data[idx++] = (u8)( + ((af->aac_section_data_resilience_flag & 0x1) << 4) | + ((af->aac_scalefactor_data_resilience_flag & 0x1) << 3) | + ((af->aac_spectral_data_resilience_flag & 0x1) << 2) | + ((af->ep_config >> 1) & 0x1)); + fmt->data[idx] = (u8)((af->ep_config & 0x1) << 7); + break; + + case AAC_OBJECT_BSAC: + fmt->data[++idx] = (u8)((af->ep_config & 0x3) << 6); + break; + + default: + pr_err("dbg unknown object type \n"); + break; + } // fmt->num_bytes = idx + 1; rpc.blocklen = idx + 1; @@ -768,8 +801,8 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, fmt->data[0], fmt->data[1], fmt->data[2], fmt->data[3], fmt->data[4], fmt->data[5], fmt->data[6], fmt->data[7]); - rpc.config.aac.bit_rate = bit_rate; - if (flags & AUDIO_FLAG_WRITE) + rpc.config.aac.bit_rate = af->bit_rate; + if (ac->flags & AUDIO_FLAG_WRITE) { rpc.opcode = ADSP_AUDIO_OPCODE_OPEN_WRITE; rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_PLAYBACK; @@ -780,13 +813,25 @@ static int audio_aac_open(struct audio_client *ac, uint32_t bufsz, rpc.stream_context = ADSP_AUDIO_DEVICE_CONTEXT_RECORD; } - /* - * Always use ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE as encoder_mode - * from Code Aurora - * by marc1706 - */ - rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; - rpc.buf_max_size = bufsz; + if ((af->sbr_on_flag == 0) && (af->sbr_ps_on_flag == 0)) + { + rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_LC_ONLY_MODE; + } + else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 0)) + { + rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_AAC_PLUS_MODE; + } + else if ((af->sbr_on_flag == 1) && (af->sbr_ps_on_flag == 1)) + { + rpc.config.aac.encoder_mode = ADSP_AUDIO_ENC_ENHANCED_AAC_PLUS_MODE; + } + else + { + pr_err("unsupported SBR flag\n"); + mutex_unlock(&open_mem_lock); + return -EINVAL; + } + rpc.buf_max_size = bufsz; /* XXX ??? */ TRACE("aac_open: opcode %x, stream_context 0x%x, " "mode %d, bytes %d, bbuffer size %d\n", @@ -1188,29 +1233,11 @@ static int acdb_init(char *filename) const struct firmware *fw; int n; - // return -ENODEV; - AUDIO_INFO("%s\n", __func__); -#ifdef CONFIG_MACH_HTCLEO - pr_info("acdb: trying htcleo.acdb\n"); - if(request_firmware(&fw, "htcleo.acdb", q6_control_device.this_device) < 0) { - pr_info("acdb: load 'htcleo.acdb' failed, trying 'default.acdb'\n"); - acdb_use_map = 0; - if (request_firmware(&fw, filename, q6_control_device.this_device) < 0) { - pr_err("acdb: load 'default.acdb' failed...\n"); - return -ENODEV; - } - } else { - pr_info("acdb: 'htcleo.acdb' found, using translation\n"); - acdb_use_map = 1; - } -#else pr_info("acdb: load '%s'\n", filename); - acd_use_map = 0; if (request_firmware(&fw, filename, q6_control_device.this_device) < 0) { pr_err("acdb: load 'default.acdb' failed...\n"); return -ENODEV; } -#endif db = (void*) fw->data; if (fw->size < sizeof(struct audio_config_database)) { @@ -1421,9 +1448,6 @@ static int acdb_get_config_table(uint32_t device_id, uint32_t sample_rate) int n; printk("table\n"); - // htcleo use custom table with wince values, it must be mapped - if(acdb_use_map) - device_id = map_cad_dev_to_virtual(device_id); db = acdb_data; for (n = 0; n < db->entry_count; n++) { @@ -2185,7 +2209,7 @@ int q6audio_set_rx_volume(int level) } EXPORT_SYMBOL_GPL(q6audio_set_rx_volume); -static int q6audio_init_rx_volumes(void) +static int q6audio_init_rx_volumes() { int vol; struct q6_device_info *di = q6_audio_devices; @@ -2604,19 +2628,14 @@ int q6audio_async(struct audio_client *ac) } -/* - * ported code for q6audio_open_aac from Code Aurora - * by marc1706 - */ -struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, - uint32_t channels, uint32_t bitrate, - uint32_t stream_format, uint32_t flags, - uint32_t acdb_id) + +struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t rate, + uint32_t flags, void *data, uint32_t acdb_id) { struct audio_client *ac; AUDIO_INFO("%s\n", __func__); - TRACE("q6audio_open_aac flags=%d samplerate=%d, channels = %d\n", flags, samplerate, channels); + TRACE("q6audio_open_aac flags=%d rate=%d\n", flags, rate); if (q6audio_init()) return 0; @@ -2629,13 +2648,12 @@ struct audio_client *q6audio_open_aac(uint32_t bufsz, uint32_t samplerate, if (ac->flags & AUDIO_FLAG_WRITE) audio_rx_path_enable(1, acdb_id); else { - if (!audio_tx_path_refcount) - tx_clk_freq = 48000; + /* TODO: consider concourrency with voice call */ + tx_clk_freq = rate; audio_tx_path_enable(1, acdb_id); } - audio_aac_open(ac, bufsz, samplerate, channels, bitrate, flags, - stream_format); + audio_aac_open(ac, bufsz, data); audio_command(ac, ADSP_AUDIO_IOCTL_CMD_SESSION_START); if (!(ac->flags & AUDIO_FLAG_WRITE)) { diff --git a/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c b/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c index 80bb903d..50c74259 100644 --- a/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c +++ b/arch/arm/mach-msm/qdsp6_1550/qcelp_in.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include From eeb52b2437bbd723f3de743a1bcd9e7a0628f556 Mon Sep 17 00:00:00 2001 From: SecureCRT Date: Fri, 4 May 2012 00:38:00 +0800 Subject: [PATCH 6/6] fixed the boot logo --- drivers/video/msm/logo.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) mode change 100644 => 100755 drivers/video/msm/logo.c diff --git a/drivers/video/msm/logo.c b/drivers/video/msm/logo.c old mode 100644 new mode 100755 index 7272765f..45ece072 --- a/drivers/video/msm/logo.c +++ b/drivers/video/msm/logo.c @@ -28,12 +28,31 @@ #define fb_height(fb) ((fb)->var.yres) #define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2) +/* 2012.5.2 SecureCRT + Since the RLE is 565 but the framebuffer need 888 format + so need to convert the format. + */ +static unsigned int rgb565to888(unsigned short rgb565_val) +{ + unsigned int rgb888_val=0; + unsigned int r = (rgb565_val>>11) & 0x1f; + unsigned int g = (rgb565_val>> 5) & 0x3f; + unsigned int b = (rgb565_val ) & 0x1f; + + rgb888_val = (r<<3) | (r>>2); + rgb888_val |=((g<<2) | (g>>4))<<8; + rgb888_val |=((b<<3) | (b>>2))<<16; + + return rgb888_val; +} + static void memset16(void *_ptr, unsigned short val, unsigned count) { - unsigned short *ptr = _ptr; + unsigned int *ptr = _ptr; + unsigned int rgb888_val = rgb565to888(val); count >>= 1; while (count--) - *ptr++ = val; + *ptr++ = rgb888_val; } /* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ @@ -42,7 +61,8 @@ int load_565rle_image(char *filename) struct fb_info *info; int fd, err = 0; unsigned count, max; - unsigned short *data, *bits, *ptr; + unsigned short *data, *ptr; + unsigned int *bits; info = registered_fb[0]; if (!info) { @@ -77,7 +97,7 @@ int load_565rle_image(char *filename) max = fb_width(info) * fb_height(info); ptr = data; - bits = (unsigned short *)(info->screen_base); + bits = (unsigned int *)(info->screen_base); while (count > 3) { unsigned n = ptr[0]; if (n > max)