History

Merge tag 'drm-misc-next-2020-08-27' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for 5.10: UAPI Changes: Cross-subsystem Changes: Core Changes: - ttm: various cleanups and reworks of the API Driver Changes: - ast: various cleanups - gma500: A few fixes, conversion to GPIOd API - hisilicon: Change of maintainer, various reworks - ingenic: Clock handling and formats support improvements - mcde: improvements to the DSI support - mgag200: Support G200 desktop cards - mxsfb: Support the i.MX7 and i.MX8M and the alpha plane - panfrost: support devfreq - ps8640: Retrieve the EDID from eDP control, misc improvements - tidss: Add a workaround for AM65xx YUV formats handling - virtio: a few cleanups, support for virtio-gpu exported resources - bridges: Support the chained bridges on more drivers, new bridges: Toshiba TC358762, Toshiba TC358775, Lontium LT9611 - panels: Convert to dev_ based logging, read orientation from the DT, various fixes, new panels: Mantix MLAF057WE51-X, Chefree CH101OLHLWH-002, Powertip PH800480T013, KingDisplay KD116N21-30NV-A010 Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 6 years ago

Commit cbc2e822 parents d012a71 cd6da0b296 files · +8739 −4394Browse files

Unified · Split

296 files
  1. Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml +176 −0
  2. Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml +127 −0
  3. Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml +215 −0
  4. Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml +3 −1
  5. Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml +70 −0
  6. Documentation/devicetree/bindings/display/panel/panel-simple.yaml +6 −0
  7. Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml +19 −21
  8. Documentation/devicetree/bindings/vendor-prefixes.yaml +8 −0
  9. Documentation/gpu/drm-uapi.rst +113 −1
  10. Documentation/gpu/pl111.rst +4 −4
  11. Documentation/gpu/todo.rst +46 −0
  12. MAINTAINERS +9 −2
  13. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c +2 −1
  14. drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c +1 −1
  15. drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c +10 −0
  16. drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c +3 −3
  17. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +2 −3
  18. drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +2 −2
  19. drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c +1 −1
  20. drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c +50 −42
  21. drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +12 −9
  22. drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h +1 −0
  23. drivers/gpu/drm/amd/amdgpu/amdgpu_object.c +6 −6
  24. drivers/gpu/drm/amd/amdgpu/amdgpu_object.h +2 −2
  25. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +58 −113
  26. drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h +33 −13
  27. drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +1 −1
  28. drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +63 −49
  29. drivers/gpu/drm/amd/amdgpu/atombios_dp.c +17 −1
  30. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +40 −1
  31. drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c +3 −0
  32. drivers/gpu/drm/arm/malidp_planes.c +1 −1
  33. drivers/gpu/drm/ast/ast_cursor.c +6 −5
  34. drivers/gpu/drm/ast/ast_dp501.c +14 −9
  35. drivers/gpu/drm/ast/ast_drv.c +36 −46
  36. drivers/gpu/drm/ast/ast_drv.h +24 −19
  37. drivers/gpu/drm/ast/ast_main.c +38 −36
  38. drivers/gpu/drm/ast/ast_mm.c +1 −1
  39. drivers/gpu/drm/ast/ast_mode.c +10 −30
  40. drivers/gpu/drm/ast/ast_post.c +3 −3
  41. drivers/gpu/drm/bridge/Kconfig +31 −0
  42. drivers/gpu/drm/bridge/Makefile +3 −0
  43. drivers/gpu/drm/bridge/analogix/analogix-anx6345.c +0 −12
  44. drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +0 −9
  45. drivers/gpu/drm/bridge/lontium-lt9611.c +1230 −0
  46. drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c +64 −45
  47. drivers/gpu/drm/bridge/nxp-ptn3460.c +43 −58
  48. drivers/gpu/drm/bridge/panel.c +0 −7
  49. drivers/gpu/drm/bridge/parade-ps8622.c +13 −87
  50. drivers/gpu/drm/bridge/parade-ps8640.c +22 −7
  51. drivers/gpu/drm/bridge/tc358762.c +280 −0
  52. drivers/gpu/drm/bridge/tc358764.c +15 −94
  53. drivers/gpu/drm/bridge/tc358767.c +66 −57
  54. drivers/gpu/drm/bridge/tc358775.c +749 −0
  55. drivers/gpu/drm/bridge/ti-sn65dsi86.c +0 −3
  56. drivers/gpu/drm/drm_bridge_connector.c +1 −0
  57. drivers/gpu/drm/drm_connector.c +47 −2
  58. drivers/gpu/drm/drm_dp_helper.c +71 −0
  59. drivers/gpu/drm/drm_gem_vram_helper.c +10 −39
  60. drivers/gpu/drm/drm_panel.c +44 −41
  61. drivers/gpu/drm/drm_syncobj.c +1 −1
  62. drivers/gpu/drm/exynos/exynos_drm_dpi.c +0 −8
  63. drivers/gpu/drm/exynos/exynos_drm_dsi.c +2 −5
  64. drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +0 −9
  65. drivers/gpu/drm/gma500/cdv_intel_dp.c +1 −1
  66. drivers/gpu/drm/gma500/mdfld_device.c +20 −0
  67. drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +1 −1
  68. drivers/gpu/drm/gma500/mdfld_dsi_output.c +28 −27
  69. drivers/gpu/drm/gma500/mdfld_dsi_output.h +1 −1
  70. drivers/gpu/drm/gma500/mdfld_output.h +1 −1
  71. drivers/gpu/drm/gma500/psb_intel_drv.h +0 −1
  72. drivers/gpu/drm/gma500/psb_intel_sdvo.c +1 −1
  73. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +19 −51
  74. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +13 −20
  75. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +2 −1
  76. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +2 −4
  77. drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +1 −1
  78. drivers/gpu/drm/i915/display/intel_dp.c +8 −0
  79. drivers/gpu/drm/imx/imx-ldb.c +0 −10
  80. drivers/gpu/drm/imx/parallel-display.c +0 −6
  81. drivers/gpu/drm/ingenic/ingenic-drm-drv.c +27 −14
  82. drivers/gpu/drm/ingenic/ingenic-ipu.c +33 −5
  83. drivers/gpu/drm/mcde/mcde_display.c +168 −50
  84. drivers/gpu/drm/mcde/mcde_drm.h +64 −3
  85. drivers/gpu/drm/mcde/mcde_drv.c +18 −63
  86. drivers/gpu/drm/mcde/mcde_dsi.c +160 −116
  87. drivers/gpu/drm/mgag200/Kconfig +5 −7
  88. drivers/gpu/drm/mgag200/mgag200_drv.c +215 −12
  89. drivers/gpu/drm/mgag200/mgag200_drv.h +16 −3
  90. drivers/gpu/drm/mgag200/mgag200_mm.c +8 −0
  91. drivers/gpu/drm/mgag200/mgag200_mode.c +93 −60
  92. drivers/gpu/drm/mgag200/mgag200_reg.h +4 −0
  93. drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c +1 −6
  94. drivers/gpu/drm/msm/dsi/dsi_manager.c +0 −1
  95. drivers/gpu/drm/mxsfb/Kconfig +5 −3
  96. drivers/gpu/drm/mxsfb/Makefile +1 −1
  97. drivers/gpu/drm/mxsfb/mxsfb_crtc.c +0 −343
  98. drivers/gpu/drm/mxsfb/mxsfb_drv.c +77 −175
  99. drivers/gpu/drm/mxsfb/mxsfb_drv.h +26 −16
  100. drivers/gpu/drm/mxsfb/mxsfb_kms.c +571 −0
  101. drivers/gpu/drm/mxsfb/mxsfb_out.c +0 −99
  102. drivers/gpu/drm/mxsfb/mxsfb_regs.h +60 −47
  103. drivers/gpu/drm/nouveau/nouveau_bo.c +18 −119
  104. drivers/gpu/drm/nouveau/nouveau_bo.h +7 −7
  105. drivers/gpu/drm/nouveau/nouveau_bo0039.c +2 −2
  106. drivers/gpu/drm/nouveau/nouveau_bo5039.c +1 −1
  107. drivers/gpu/drm/nouveau/nouveau_bo74c1.c +1 −1
  108. drivers/gpu/drm/nouveau/nouveau_bo85b5.c +1 −1
  109. drivers/gpu/drm/nouveau/nouveau_bo9039.c +1 −1
  110. drivers/gpu/drm/nouveau/nouveau_bo90b5.c +1 −1
  111. drivers/gpu/drm/nouveau/nouveau_boa0b5.c +1 −1
  112. drivers/gpu/drm/nouveau/nouveau_drv.h +1 −1
  113. drivers/gpu/drm/nouveau/nouveau_mem.c +4 −4
  114. drivers/gpu/drm/nouveau/nouveau_mem.h +5 −5
  115. drivers/gpu/drm/nouveau/nouveau_sgdma.c +2 −2
  116. drivers/gpu/drm/nouveau/nouveau_ttm.c +127 −49
  117. drivers/gpu/drm/nouveau/nouveau_ttm.h +3 −3
  118. drivers/gpu/drm/nouveau/nv17_fence.c +1 −1
  119. drivers/gpu/drm/nouveau/nv50_fence.c +1 −1
  120. drivers/gpu/drm/omapdrm/dss/hdmi4.c +0 −1
  121. drivers/gpu/drm/omapdrm/dss/hdmi5.c +0 −1
  122. drivers/gpu/drm/omapdrm/dss/venc.c +1 −1
  123. drivers/gpu/drm/omapdrm/omap_drv.c +0 −17
  124. drivers/gpu/drm/panel/Kconfig +11 −0
  125. drivers/gpu/drm/panel/Makefile +1 −0
  126. drivers/gpu/drm/panel/panel-arm-versatile.c +3 −1
  127. drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c +1 −5
  128. drivers/gpu/drm/panel/panel-boe-himax8279d.c +18 −30
  129. drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c +11 −1
  130. drivers/gpu/drm/panel/panel-elida-kd35t133.c +19 −32
  131. drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c +9 −14
  132. drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c +10 −15
  133. drivers/gpu/drm/panel/panel-ilitek-ili9322.c +4 −3
  134. drivers/gpu/drm/panel/panel-ilitek-ili9881c.c +255 −22
  135. drivers/gpu/drm/panel/panel-innolux-p079zca.c +12 −23
  136. drivers/gpu/drm/panel/panel-jdi-lt070me05000.c +2 −2
  137. drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c +15 −22
  138. drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c +20 −38
  139. drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c +17 −32
  140. drivers/gpu/drm/panel/panel-lg-lb035q02.c +3 −1
  141. drivers/gpu/drm/panel/panel-lg-lg4573.c +3 −1
  142. drivers/gpu/drm/panel/panel-lvds.c +10 −3
  143. drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c +328 −0
  144. drivers/gpu/drm/panel/panel-nec-nl8048hl11.c +3 −1
  145. drivers/gpu/drm/panel/panel-novatek-nt35510.c +31 −29
  146. drivers/gpu/drm/panel/panel-novatek-nt39016.c +16 −30
  147. drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c +3 −1
  148. drivers/gpu/drm/panel/panel-orisetech-otm8009a.c +6 −7
  149. drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c +3 −1
  150. drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c +3 −1
  151. drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +2 −4
  152. drivers/gpu/drm/panel/panel-raydium-rm67191.c +16 −21
  153. drivers/gpu/drm/panel/panel-raydium-rm68200.c +8 −10
  154. drivers/gpu/drm/panel/panel-ronbo-rb070d30.c +8 −12
  155. drivers/gpu/drm/panel/panel-samsung-ld9040.c +4 −3
  156. drivers/gpu/drm/panel/panel-samsung-s6d16d0.c +9 −18
  157. drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c +2 −7
  158. drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c +2 −7
  159. drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +12 −14
  160. drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c +1 −5
  161. drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c +2 −5
  162. drivers/gpu/drm/panel/panel-seiko-43wvf1g.c +1 −3
  163. drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +3 −1
  164. drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c +3 −1
  165. drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c +3 −1
  166. drivers/gpu/drm/panel/panel-simple.c +180 −21
  167. drivers/gpu/drm/panel/panel-sitronix-st7701.c +5 −9
  168. drivers/gpu/drm/panel/panel-sitronix-st7703.c +23 −38
  169. drivers/gpu/drm/panel/panel-sitronix-st7789v.c +1 −3
  170. drivers/gpu/drm/panel/panel-sony-acx424akp.c +29 −56
  171. drivers/gpu/drm/panel/panel-sony-acx565akm.c +1 −6
  172. drivers/gpu/drm/panel/panel-tpo-td028ttec1.c +3 −1
  173. drivers/gpu/drm/panel/panel-tpo-td043mtea1.c +1 −5
  174. drivers/gpu/drm/panel/panel-tpo-tpg110.c +20 −22
  175. drivers/gpu/drm/panel/panel-truly-nt35597.c +21 −42
  176. drivers/gpu/drm/panel/panel-visionox-rm69299.c +13 −28
  177. drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c +19 −32
  178. drivers/gpu/drm/panfrost/panfrost_devfreq.c +116 −59
  179. drivers/gpu/drm/panfrost/panfrost_devfreq.h +28 −2
  180. drivers/gpu/drm/panfrost/panfrost_device.c +39 −22
  181. drivers/gpu/drm/panfrost/panfrost_device.h +4 −10
  182. drivers/gpu/drm/panfrost/panfrost_drv.c +3 −13
  183. drivers/gpu/drm/panfrost/panfrost_gpu.c +12 −2
  184. drivers/gpu/drm/panfrost/panfrost_job.c +3 −7
  185. drivers/gpu/drm/panfrost/panfrost_perfcnt.c +7 −3
  186. drivers/gpu/drm/pl111/pl111_drv.c +5 −15
  187. drivers/gpu/drm/qxl/qxl_cmd.c +1 −1
  188. drivers/gpu/drm/qxl/qxl_display.c +11 −10
  189. drivers/gpu/drm/qxl/qxl_drv.c +3 −3
  190. drivers/gpu/drm/qxl/qxl_drv.h +1 −1
  191. drivers/gpu/drm/qxl/qxl_ioctl.c +1 −1
  192. drivers/gpu/drm/qxl/qxl_object.c +2 −2
  193. drivers/gpu/drm/qxl/qxl_object.h +2 −2
  194. drivers/gpu/drm/qxl/qxl_ttm.c +24 −51
  195. drivers/gpu/drm/radeon/radeon.h +1 −1
  196. drivers/gpu/drm/radeon/radeon_gem.c +2 −2
  197. drivers/gpu/drm/radeon/radeon_object.c +1 −1
  198. drivers/gpu/drm/radeon/radeon_object.h +1 −1
  199. drivers/gpu/drm/radeon/radeon_ttm.c +41 −82
  200. drivers/gpu/drm/radeon/radeon_vm.c +1 −1
  201. drivers/gpu/drm/rcar-du/rcar_lvds.c +1 −5
  202. drivers/gpu/drm/rockchip/rockchip_lvds.c +0 −9
  203. drivers/gpu/drm/sti/sti_dvo.c +0 −2
  204. drivers/gpu/drm/sun4i/sun4i_backend.c +1 −1
  205. drivers/gpu/drm/sun4i/sun4i_framebuffer.c +1 −1
  206. drivers/gpu/drm/sun4i/sun4i_frontend.c +1 −1
  207. drivers/gpu/drm/sun4i/sun4i_lvds.c +1 −10
  208. drivers/gpu/drm/sun4i/sun4i_rgb.c +2 −11
  209. drivers/gpu/drm/sun4i/sun4i_tcon.c +1 −1
  210. drivers/gpu/drm/sun4i/sun4i_tv.c +3 −3
  211. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +1 −4
  212. drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c +1 −1
  213. drivers/gpu/drm/sun4i/sun8i_mixer.c +1 −1
  214. drivers/gpu/drm/sun4i/sun8i_ui_layer.c +1 −1
  215. drivers/gpu/drm/sun4i/sun8i_vi_layer.c +1 −1
  216. drivers/gpu/drm/tegra/dsi.c +1 −3
  217. drivers/gpu/drm/tegra/output.c +0 −10
  218. drivers/gpu/drm/tidss/tidss_dispc.c +28 −4
  219. drivers/gpu/drm/tidss/tidss_dispc.h +4 −0
  220. drivers/gpu/drm/ttm/Makefile +2 −1
  221. drivers/gpu/drm/ttm/ttm_agp_backend.c +1 −1
  222. drivers/gpu/drm/ttm/ttm_bo.c +89 −258
  223. drivers/gpu/drm/ttm/ttm_bo_util.c +55 −49
  224. drivers/gpu/drm/ttm/ttm_bo_vm.c +3 −5
  225. drivers/gpu/drm/ttm/ttm_execbuf_util.c +2 −10
  226. drivers/gpu/drm/ttm/ttm_range_manager.c +60 −29
  227. drivers/gpu/drm/ttm/ttm_resource.c +151 −0
  228. drivers/gpu/drm/ttm/ttm_tt.c +4 −2
  229. drivers/gpu/drm/v3d/v3d_drv.c +1 −12
  230. drivers/gpu/drm/vgem/vgem_drv.c +1 −1
  231. drivers/gpu/drm/virtio/Kconfig +1 −0
  232. drivers/gpu/drm/virtio/virtgpu_display.c +0 −2
  233. drivers/gpu/drm/virtio/virtgpu_drv.c +3 −0
  234. drivers/gpu/drm/virtio/virtgpu_drv.h +21 −0
  235. drivers/gpu/drm/virtio/virtgpu_gem.c +1 −2
  236. drivers/gpu/drm/virtio/virtgpu_kms.c +4 −0
  237. drivers/gpu/drm/virtio/virtgpu_object.c +7 −1
  238. drivers/gpu/drm/virtio/virtgpu_prime.c +93 −3
  239. drivers/gpu/drm/virtio/virtgpu_vq.c +55 −0
  240. drivers/gpu/drm/vkms/vkms_composer.c +18 −4
  241. drivers/gpu/drm/vkms/vkms_drv.c +1 −1
  242. drivers/gpu/drm/vmwgfx/vmwgfx_bo.c +2 −2
  243. drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +54 −19
  244. drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +10 −8
  245. drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c +42 −33
  246. drivers/gpu/drm/vmwgfx/vmwgfx_mob.c +3 −57
  247. drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +1 −1
  248. drivers/gpu/drm/vmwgfx/vmwgfx_thp.c +45 −28
  249. drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c +39 −82
  250. drivers/video/fbdev/acornfb.c +1 −1
  251. drivers/video/fbdev/arcfb.c +1 −1
  252. drivers/video/fbdev/atmel_lcdfb.c +2 −2
  253. drivers/video/fbdev/aty/radeon_pm.c +3 −3
  254. drivers/video/fbdev/cirrusfb.c +2 −2
  255. drivers/video/fbdev/controlfb.c +1 −1
  256. drivers/video/fbdev/core/fbmem.c +6 −6
  257. drivers/video/fbdev/fsl-diu-fb.c +2 −2
  258. drivers/video/fbdev/gxt4500.c +1 −1
  259. drivers/video/fbdev/i740fb.c +1 −1
  260. drivers/video/fbdev/offb.c +2 −2
  261. drivers/video/fbdev/omap/lcdc.c +2 −2
  262. drivers/video/fbdev/omap/omapfb_main.c +10 −10
  263. drivers/video/fbdev/omap2/omapfb/dss/dispc.c +2 −2
  264. drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c +1 −1
  265. drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c +1 −1
  266. drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c +1 −1
  267. drivers/video/fbdev/omap2/omapfb/omapfb-main.c +1 −1
  268. drivers/video/fbdev/pm2fb.c +2 −2
  269. drivers/video/fbdev/pvr2fb.c +2 −0
  270. drivers/video/fbdev/pxafb.c +1 −1
  271. drivers/video/fbdev/s3c-fb.c +3 −3
  272. drivers/video/fbdev/sa1100fb.c +1 −1
  273. drivers/video/fbdev/savage/savagefb_driver.c +1 −2
  274. drivers/video/fbdev/sh_mobile_lcdcfb.c +2 −2
  275. drivers/video/fbdev/sm501fb.c +1 −1
  276. drivers/video/fbdev/tdfxfb.c +1 −1
  277. drivers/video/fbdev/xen-fbfront.c +1 −1
  278. drivers/virtio/Kconfig +7 −0
  279. drivers/virtio/Makefile +1 −0
  280. drivers/virtio/virtio.c +6 −0
  281. drivers/virtio/virtio_dma_buf.c +88 −0
  282. include/drm/drm_connector.h +3 −0
  283. include/drm/drm_dp_helper.h +8 −0
  284. include/drm/drm_mode_config.h +6 −0
  285. include/drm/drm_panel.h +11 −4
  286. include/drm/ttm/ttm_bo_api.h +11 −98
  287. include/drm/ttm/ttm_bo_driver.h +91 −264
  288. include/drm/ttm/ttm_resource.h +261 −0
  289. include/drm/ttm/ttm_tt.h +5 −5
  290. include/linux/fb.h +9 −9
  291. include/linux/moduleparam.h +6 −1
  292. include/linux/virtio.h +1 −0
  293. include/linux/virtio_dma_buf.h +37 −0
  294. include/uapi/drm/drm_mode.h +13 −8
  295. include/uapi/linux/virtio_gpu.h +19 −0
  296. kernel/params.c +9 −8
Documentation/devicetree/bindings/display/bridge/lontium,lt9611.yaml+176−0
@@ -0,0 +1,176 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/display/bridge/lontium,lt9611.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Lontium LT9611 2 Port MIPI to HDMI Bridge
8
9maintainers:
10 - Vinod Koul <vkoul@kernel.org>
11
12description: |
13 The LT9611 is a bridge device which converts DSI to HDMI
14
15properties:
16 compatible:
17 enum:
18 - lontium,lt9611
19
20 reg:
21 maxItems: 1
22
23 "#sound-dai-cells":
24 const: 1
25
26 interrupts:
27 maxItems: 1
28
29 reset-gpios:
30 maxItems: 1
31 description: GPIO connected to active high RESET pin.
32
33 vdd-supply:
34 description: Regulator for 1.8V MIPI phy power.
35
36 vcc-supply:
37 description: Regulator for 3.3V IO power.
38
39 ports:
40 type: object
41
42 properties:
43 "#address-cells":
44 const: 1
45
46 "#size-cells":
47 const: 0
48
49 port@0:
50 type: object
51 description: |
52 Primary MIPI port-1 for MIPI input
53
54 properties:
55 reg:
56 const: 0
57
58 patternProperties:
59 "^endpoint(@[0-9])$":
60 type: object
61 additionalProperties: false
62
63 properties:
64 remote-endpoint:
65 $ref: /schemas/types.yaml#/definitions/phandle
66
67 required:
68 - reg
69
70 port@1:
71 type: object
72 description: |
73 Additional MIPI port-2 for MIPI input, used in combination
74 with primary MIPI port-1 to drive higher resolution displays
75
76 properties:
77 reg:
78 const: 1
79
80 patternProperties:
81 "^endpoint(@[0-9])$":
82 type: object
83 additionalProperties: false
84
85 properties:
86 remote-endpoint:
87 $ref: /schemas/types.yaml#/definitions/phandle
88
89 required:
90 - reg
91
92 port@2:
93 type: object
94 description: |
95 HDMI port for HDMI output
96
97 properties:
98 reg:
99 const: 2
100
101 patternProperties:
102 "^endpoint(@[0-9])$":
103 type: object
104 additionalProperties: false
105
106 properties:
107 remote-endpoint:
108 $ref: /schemas/types.yaml#/definitions/phandle
109
110 required:
111 - reg
112
113 required:
114 - "#address-cells"
115 - "#size-cells"
116 - port@0
117 - port@2
118
119required:
120 - compatible
121 - reg
122 - interrupts
123 - vdd-supply
124 - vcc-supply
125 - ports
126
127additionalProperties: false
128
129examples:
130 - |
131 #include <dt-bindings/gpio/gpio.h>
132 #include <dt-bindings/interrupt-controller/irq.h>
133
134 i2c10 {
135 #address-cells = <1>;
136 #size-cells = <0>;
137
138 hdmi-bridge@3b {
139 compatible = "lontium,lt9611";
140 reg = <0x3b>;
141
142 reset-gpios = <&tlmm 128 GPIO_ACTIVE_HIGH>;
143 interrupts-extended = <&tlmm 84 IRQ_TYPE_EDGE_FALLING>;
144
145 vdd-supply = <&lt9611_1v8>;
146 vcc-supply = <&lt9611_3v3>;
147
148 ports {
149 #address-cells = <1>;
150 #size-cells = <0>;
151
152 port@0 {
153 reg = <0>;
154 lt9611_a: endpoint {
155 remote-endpoint = <&dsi0_out>;
156 };
157 };
158
159 port@1 {
160 reg = <1>;
161 lt9611_b: endpoint {
162 remote-endpoint = <&dsi1_out>;
163 };
164 };
165
166 port@2 {
167 reg = <2>;
168 lt9611_out: endpoint {
169 remote-endpoint = <&hdmi_con>;
170 };
171 };
172 };
173 };
174 };
175
176...
Documentation/devicetree/bindings/display/bridge/toshiba,tc358762.yaml+127−0
@@ -0,0 +1,127 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358762.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Toshiba TC358762 MIPI DSI to MIPI DPI bridge
8
9maintainers:
10 - Marek Vasut <marex@denx.de>
11
12description: |
13 The TC358762 is bridge device which converts MIPI DSI to MIPI DPI.
14
15properties:
16 compatible:
17 enum:
18 - toshiba,tc358762
19
20 reg:
21 maxItems: 1
22 description: virtual channel number of a DSI peripheral
23
24 vddc-supply:
25 description: Regulator for 1.2V internal core power.
26
27 ports:
28 type: object
29
30 properties:
31 "#address-cells":
32 const: 1
33
34 "#size-cells":
35 const: 0
36
37 port@0:
38 type: object
39 additionalProperties: false
40
41 description: |
42 Video port for MIPI DSI input
43
44 properties:
45 reg:
46 const: 0
47
48 patternProperties:
49 endpoint:
50 type: object
51 additionalProperties: false
52
53 properties:
54 remote-endpoint: true
55
56 required:
57 - reg
58
59 port@1:
60 type: object
61 additionalProperties: false
62
63 description: |
64 Video port for MIPI DPI output (panel or connector).
65
66 properties:
67 reg:
68 const: 1
69
70 patternProperties:
71 endpoint:
72 type: object
73 additionalProperties: false
74
75 properties:
76 remote-endpoint: true
77
78 required:
79 - reg
80
81 required:
82 - "#address-cells"
83 - "#size-cells"
84 - port@0
85 - port@1
86
87required:
88 - compatible
89 - reg
90 - vddc-supply
91 - ports
92
93additionalProperties: false
94
95examples:
96 - |
97 i2c1 {
98 #address-cells = <1>;
99 #size-cells = <0>;
100
101 bridge@0 {
102 reg = <0>;
103 compatible = "toshiba,tc358762";
104 vddc-supply = <&vcc_1v2_reg>;
105
106 ports {
107 #address-cells = <1>;
108 #size-cells = <0>;
109
110 port@0 {
111 reg = <0>;
112 bridge_in: endpoint {
113 remote-endpoint = <&dsi_out>;
114 };
115 };
116
117 port@1 {
118 reg = <1>;
119 bridge_out: endpoint {
120 remote-endpoint = <&panel_in>;
121 };
122 };
123 };
124 };
125 };
126
127...
Documentation/devicetree/bindings/display/bridge/toshiba,tc358775.yaml+215−0
@@ -0,0 +1,215 @@
1# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/display/bridge/toshiba,tc358775.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Toshiba TC358775 DSI to LVDS bridge bindings
8
9maintainers:
10 - Vinay Simha BN <simhavcs@gmail.com>
11
12description: |
13 This binding supports DSI to LVDS bridge TC358775
14
15 MIPI DSI-RX Data 4-lane, CLK 1-lane with data rates up to 800 Mbps/lane.
16 Video frame size:
17 Up to 1600x1200 24-bit/pixel resolution for single-link LVDS display panel
18 limited by 135 MHz LVDS speed
19 Up to WUXGA (1920x1200 24-bit pixels) resolution for dual-link LVDS display
20 panel, limited by 270 MHz LVDS speed.
21
22properties:
23 compatible:
24 const: toshiba,tc358775
25
26 reg:
27 maxItems: 1
28 description: i2c address of the bridge, 0x0f
29
30 vdd-supply:
31 maxItems: 1
32 description: 1.2V LVDS Power Supply
33
34 vddio-supply:
35 maxItems: 1
36 description: 1.8V IO Power Supply
37
38 stby-gpios:
39 maxItems: 1
40 description: Standby pin, Low active
41
42 reset-gpios:
43 maxItems: 1
44 description: Hardware reset, Low active
45
46 ports:
47 type: object
48 description:
49 A node containing input and output port nodes with endpoint definitions
50 as documented in
51 Documentation/devicetree/bindings/media/video-interfaces.txt
52 properties:
53 "#address-cells":
54 const: 1
55
56 "#size-cells":
57 const: 0
58
59 port@0:
60 type: object
61 description: |
62 DSI Input. The remote endpoint phandle should be a
63 reference to a valid mipi_dsi_host device node.
64
65 port@1:
66 type: object
67 description: |
68 Video port for LVDS output (panel or connector).
69
70 port@2:
71 type: object
72 description: |
73 Video port for Dual link LVDS output (panel or connector).
74
75 required:
76 - port@0
77 - port@1
78
79required:
80 - compatible
81 - reg
82 - vdd-supply
83 - vddio-supply
84 - stby-gpios
85 - reset-gpios
86 - ports
87
88examples:
89 - |
90 #include <dt-bindings/gpio/gpio.h>
91
92 /* For single-link LVDS display panel */
93
94 i2c@78b8000 {
95 /* On High speed expansion */
96 label = "HS-I2C2";
97 reg = <0x078b8000 0x500>;
98 clock-frequency = <400000>; /* fastmode operation */
99 #address-cells = <1>;
100 #size-cells = <0>;
101
102 tc_bridge: bridge@f {
103 compatible = "toshiba,tc358775";
104 reg = <0x0f>;
105
106 vdd-supply = <&pm8916_l2>;
107 vddio-supply = <&pm8916_l6>;
108
109 stby-gpios = <&msmgpio 99 GPIO_ACTIVE_LOW>;
110 reset-gpios = <&msmgpio 72 GPIO_ACTIVE_LOW>;
111
112 ports {
113 #address-cells = <1>;
114 #size-cells = <0>;
115
116 port@0 {
117 reg = <0>;
118 d2l_in_test: endpoint {
119 remote-endpoint = <&dsi0_out>;
120 };
121 };
122
123 port@1 {
124 reg = <1>;
125 lvds_out: endpoint {
126 remote-endpoint = <&panel_in>;
127 };
128 };
129 };
130 };
131 };
132
133 dsi@1a98000 {
134 reg = <0x1a98000 0x25c>;
135 reg-names = "dsi_ctrl";
136
137 ports {
138 #address-cells = <1>;
139 #size-cells = <0>;
140 port@1 {
141 reg = <1>;
142 dsi0_out: endpoint {
143 remote-endpoint = <&d2l_in_test>;
144 data-lanes = <0 1 2 3>;
145 };
146 };
147 };
148 };
149
150 - |
151 /* For dual-link LVDS display panel */
152
153 i2c@78b8000 {
154 /* On High speed expansion */
155 label = "HS-I2C2";
156 reg = <0x078b8000 0x500>;
157 clock-frequency = <400000>; /* fastmode operation */
158 #address-cells = <1>;
159 #size-cells = <0>;
160
161 tc_bridge_dual: bridge@f {
162 compatible = "toshiba,tc358775";
163 reg = <0x0f>;
164
165 vdd-supply = <&pm8916_l2>;
166 vddio-supply = <&pm8916_l6>;
167
168 stby-gpios = <&msmgpio 99 GPIO_ACTIVE_LOW>;
169 reset-gpios = <&msmgpio 72 GPIO_ACTIVE_LOW>;
170
171 ports {
172 #address-cells = <1>;
173 #size-cells = <0>;
174
175 port@0 {
176 reg = <0>;
177 d2l_in_dual: endpoint {
178 remote-endpoint = <&dsi0_out_dual>;
179 };
180 };
181
182 port@1 {
183 reg = <1>;
184 lvds0_out: endpoint {
185 remote-endpoint = <&panel_in0>;
186 };
187 };
188
189 port@2 {
190 reg = <2>;
191 lvds1_out: endpoint {
192 remote-endpoint = <&panel_in1>;
193 };
194 };
195 };
196 };
197 };
198
199 dsi@1a98000 {
200 reg = <0x1a98000 0x25c>;
201 reg-names = "dsi_ctrl";
202
203 ports {
204 #address-cells = <1>;
205 #size-cells = <0>;
206 port@1 {
207 reg = <1>;
208 dsi0_out_dual: endpoint {
209 remote-endpoint = <&d2l_in_dual>;
210 data-lanes = <0 1 2 3>;
211 };
212 };
213 };
214 };
215...
Documentation/devicetree/bindings/display/panel/ilitek,ili9881c.yaml+3−1
@@ -13,7 +13,9 @@ properties: · 12 unmodified lines
13 compatible:13 compatible:
14 items:14 items:
15 - enum:15 - enum:
16 - bananapi,lhr050h4116 - bananapi,lhr050h41
17 - feixin,k101-im2byl02
18
17 - const: ilitek,ili9881c19 - const: ilitek,ili9881c
18 20
19 backlight: true21 backlight: true
Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml+70−0
@@ -0,0 +1,70 @@
1# SPDX-License-Identifier: (GPL-2.0-only or BSD-2-Clause)
2%YAML 1.2
3---
4$id: http://devicetree.org/schemas/display/panel/mantix,mlaf057we51-x.yaml#
5$schema: http://devicetree.org/meta-schemas/core.yaml#
6
7title: Mantix MLAF057WE51-X 5.7" 720x1440 TFT LCD panel
8
9maintainers:
10 - Guido Günther <agx@sigxcpu.org>
11
12description:
13 Mantix MLAF057WE51 X is a 720x1440 TFT LCD panel connected using
14 a MIPI-DSI video interface.
15
16allOf:
17 - $ref: panel-common.yaml#
18
19properties:
20 compatible:
21 enum:
22 - mantix,mlaf057we51-x
23
24 port: true
25 reg:
26 maxItems: 1
27 description: DSI virtual channel
28
29 avdd-supply:
30 description: Positive analog power supply
31
32 avee-supply:
33 description: Negative analog power supply
34
35 vddi-supply:
36 description: 1.8V I/O voltage supply
37
38 reset-gpios: true
39
40 backlight: true
41
42required:
43 - compatible
44 - reg
45 - avdd-supply
46 - avee-supply
47 - vddi-supply
48 - reset-gpios
49
50additionalProperties: false
51
52examples:
53 - |
54 #include <dt-bindings/gpio/gpio.h>
55
56 dsi {
57 #address-cells = <1>;
58 #size-cells = <0>;
59 panel@0 {
60 compatible = "mantix,mlaf057we51-x";
61 reg = <0>;
62 avdd-supply = <&reg_avdd>;
63 avee-supply = <&reg_avee>;
64 vddi-supply = <&reg_1v8_p>;
65 reset-gpios = <&gpio1 29 GPIO_ACTIVE_LOW>;
66 backlight = <&backlight>;
67 };
68 };
69
70...
Documentation/devicetree/bindings/display/panel/panel-simple.yaml+6−0
@@ -87,6 +87,8 @@ properties: · 86 unmodified lines
87 - cdtech,s070swv29hg-dc4487 - cdtech,s070swv29hg-dc44
88 # CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel88 # CDTech(H.K.) Electronics Limited 7" 800x480 color TFT-LCD panel
89 - cdtech,s070wv95-ct1689 - cdtech,s070wv95-ct16
90 # Chefree CH101OLHLWH-002 10.1" (1280x800) color TFT LCD panel
91 - chefree,ch101olhlwh-002
90 # Chunghwa Picture Tubes Ltd. 7" WXGA TFT LCD panel92 # Chunghwa Picture Tubes Ltd. 7" WXGA TFT LCD panel
91 - chunghwa,claa070wp03xg93 - chunghwa,claa070wp03xg
92 # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel94 # Chunghwa Picture Tubes Ltd. 10.1" WXGA TFT LCD panel
@@ -159,6 +161,8 @@ properties: · 66 unmodified lines
159 - innolux,n156bge-l21161 - innolux,n156bge-l21
160 # Innolux Corporation 7.0" WSVGA (1024x600) TFT LCD panel162 # Innolux Corporation 7.0" WSVGA (1024x600) TFT LCD panel
161 - innolux,zj070na-01p163 - innolux,zj070na-01p
164 # King & Display KD116N21-30NV-A010 eDP TFT LCD panel
165 - kingdisplay,kd116n21-30nv-a010
162 # Kaohsiung Opto-Electronics Inc. 5.7" QVGA (320 x 240) TFT LCD panel166 # Kaohsiung Opto-Electronics Inc. 5.7" QVGA (320 x 240) TFT LCD panel
163 - koe,tx14d24vm1bpa167 - koe,tx14d24vm1bpa
164 # Kaohsiung Opto-Electronics Inc. 10.1" WUXGA (1920 x 1200) LVDS TFT LCD panel168 # Kaohsiung Opto-Electronics Inc. 10.1" WUXGA (1920 x 1200) LVDS TFT LCD panel
@@ -219,6 +223,8 @@ properties: · 54 unmodified lines
219 - osddisplays,osd070t1718-19ts223 - osddisplays,osd070t1718-19ts
220 # One Stop Displays OSD101T2045-53TS 10.1" 1920x1200 panel224 # One Stop Displays OSD101T2045-53TS 10.1" 1920x1200 panel
221 - osddisplays,osd101t2045-53ts225 - osddisplays,osd101t2045-53ts
226 # POWERTIP PH800480T013-IDF2 7.0" WVGA TFT LCD panel
227 - powertip,ph800480t013-idf02
222 # QiaoDian XianShi Corporation 4"3 TFT LCD panel228 # QiaoDian XianShi Corporation 4"3 TFT LCD panel
223 - qiaodian,qd43003c0-40229 - qiaodian,qd43003c0-40
224 # Rocktech Displays Ltd. RK101II01D-CT 10.1" TFT 1280x800230 # Rocktech Displays Ltd. RK101II01D-CT 10.1" TFT 1280x800
Documentation/devicetree/bindings/display/panel/rocktech,jh057n00900.yaml+19−21
@@ -8,10 +8,11 @@ title: Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel · 7 unmodified lines
8 8
9maintainers:9maintainers:
10 - Ondrej Jirman <megi@xff.cz>10 - Ondrej Jirman <megi@xff.cz>
11 - Guido Gŭnther <agx@sigxcpu.org>
11 12
12description: |13description:
13 Rocktech JH057N00900 is a 720x1440 TFT LCD panel14 Rocktech JH057N00900 is a 720x1440 TFT LCD panel
14 connected using a MIPI-DSI video interface.15 connected using a MIPI-DSI video interface.
15 16
16allOf:17allOf:
17 - $ref: panel-common.yaml#18 - $ref: panel-common.yaml#
@@ -19,9 +20,9 @@ allOf: · 1 unmodified line
19properties:20properties:
20 compatible:21 compatible:
21 enum:22 enum:
22 # Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel23 # Rocktech JH057N00900 5.5" 720x1440 TFT LCD panel
23 - rocktech,jh057n0090024 - rocktech,jh057n00900
24 # Xingbangda XBD599 5.99" 720x1440 TFT LCD panel25 # Xingbangda XBD599 5.99" 720x1440 TFT LCD panel
25 - xingbangda,xbd59926 - xingbangda,xbd599
26 27
27 port: true28 port: true
@@ -35,13 +36,9 @@ properties: · 7 unmodified lines
35 iovcc-supply:36 iovcc-supply:
36 description: I/O voltage supply37 description: I/O voltage supply
37 38
38 reset-gpios:39 reset-gpios: true
39 description: GPIO used for the reset pin
40 maxItems: 1
41 40
42 backlight:41 backlight: true
43 description: Backlight used by the panel
44 $ref: "/schemas/types.yaml#/definitions/phandle"
45 42
46required:43required:
47 - compatible44 - compatible
@@ -57,15 +54,16 @@ examples: · 9 unmodified lines
57 #include <dt-bindings/gpio/gpio.h>54 #include <dt-bindings/gpio/gpio.h>
58 55
59 dsi {56 dsi {
60 #address-cells = <1>;57 #address-cells = <1>;
61 #size-cells = <0>;58 #size-cells = <0>;
62 panel@0 {59 panel@0 {
63 compatible = "rocktech,jh057n00900";60 compatible = "rocktech,jh057n00900";
64 reg = <0>;61 reg = <0>;
65 vcc-supply = <&reg_2v8_p>;62 vcc-supply = <&reg_2v8_p>;
66 iovcc-supply = <&reg_1v8_p>;63 iovcc-supply = <&reg_1v8_p>;
67 reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>;64 reset-gpios = <&gpio3 13 GPIO_ACTIVE_LOW>;
68 backlight = <&backlight>;65 backlight = <&backlight>;
69 };66 };
70 };67 };
68
71...69...
Documentation/devicetree/bindings/vendor-prefixes.yaml+8−0
@@ -197,6 +197,8 @@ patternProperties: · 196 unmodified lines
197 description: Ceva, Inc.197 description: Ceva, Inc.
198 "^checkpoint,.*":198 "^checkpoint,.*":
199 description: Check Point Software Technologies Ltd.199 description: Check Point Software Technologies Ltd.
200 "^chefree,.*":
201 description: Chefree Technology Corp.
200 "^chipidea,.*":202 "^chipidea,.*":
201 description: Chipidea, Inc203 description: Chipidea, Inc
202 "^chipone,.*":204 "^chipone,.*":
@@ -601,6 +603,8 @@ patternProperties: · 398 unmodified lines
601 description: Logic Technologies Limited603 description: Logic Technologies Limited
602 "^longcheer,.*":604 "^longcheer,.*":
603 description: Longcheer Technology (Shanghai) Co., Ltd.605 description: Longcheer Technology (Shanghai) Co., Ltd.
606 "^lontium,.*":
607 description: Lontium Semiconductor Corporation
604 "^loongson,.*":608 "^loongson,.*":
605 description: Loongson Technology Corporation Limited609 description: Loongson Technology Corporation Limited
606 "^lsi,.*":610 "^lsi,.*":
@@ -611,6 +615,8 @@ patternProperties: · 4 unmodified lines
611 description: Linux Automation GmbH615 description: Linux Automation GmbH
612 "^macnica,.*":616 "^macnica,.*":
613 description: Macnica Americas617 description: Macnica Americas
618 "^mantix,.*":
619 description: Mantix Display Technology Co.,Ltd.
614 "^mapleboard,.*":620 "^mapleboard,.*":
615 description: Mapleboard.org621 description: Mapleboard.org
616 "^marvell,.*":622 "^marvell,.*":
@@ -830,6 +836,8 @@ patternProperties: · 213 unmodified lines
830 description: Poslab Technology Co., Ltd.836 description: Poslab Technology Co., Ltd.
831 "^pov,.*":837 "^pov,.*":
832 description: Point of View International B.V.838 description: Point of View International B.V.
839 "^powertip,.*":
840 description: Powertip Tech. Corp.
833 "^powervr,.*":841 "^powervr,.*":
834 description: PowerVR (deprecated, use img)842 description: PowerVR (deprecated, use img)
835 "^primux,.*":843 "^primux,.*":
Documentation/gpu/drm-uapi.rst+113−1
@@ -1,3 +1,5 @@
1.. Copyright 2020 DisplayLink (UK) Ltd.
2
1===================3===================
2Userland interfaces4Userland interfaces
3===================5===================
@@ -162,6 +164,116 @@ other hand, a driver requires shared state between clients which is · 158 unmodified lines
162visible to user-space and accessible beyond open-file boundaries, they164visible to user-space and accessible beyond open-file boundaries, they
163cannot support render nodes.165cannot support render nodes.
164 166
167Device Hot-Unplug
168=================
169
170.. note::
171 The following is the plan. Implementation is not there yet
172 (2020 May).
173
174Graphics devices (display and/or render) may be connected via USB (e.g.
175display adapters or docking stations) or Thunderbolt (e.g. eGPU). An end
176user is able to hot-unplug this kind of devices while they are being
177used, and expects that the very least the machine does not crash. Any
178damage from hot-unplugging a DRM device needs to be limited as much as
179possible and userspace must be given the chance to handle it if it wants
180to. Ideally, unplugging a DRM device still lets a desktop continue to
181run, but that is going to need explicit support throughout the whole
182graphics stack: from kernel and userspace drivers, through display
183servers, via window system protocols, and in applications and libraries.
184
185Other scenarios that should lead to the same are: unrecoverable GPU
186crash, PCI device disappearing off the bus, or forced unbind of a driver
187from the physical device.
188
189In other words, from userspace perspective everything needs to keep on
190working more or less, until userspace stops using the disappeared DRM
191device and closes it completely. Userspace will learn of the device
192disappearance from the device removed uevent, ioctls returning ENODEV
193(or driver-specific ioctls returning driver-specific things), or open()
194returning ENXIO.
195
196Only after userspace has closed all relevant DRM device and dmabuf file
197descriptors and removed all mmaps, the DRM driver can tear down its
198instance for the device that no longer exists. If the same physical
199device somehow comes back in the mean time, it shall be a new DRM
200device.
201
202Similar to PIDs, chardev minor numbers are not recycled immediately. A
203new DRM device always picks the next free minor number compared to the
204previous one allocated, and wraps around when minor numbers are
205exhausted.
206
207The goal raises at least the following requirements for the kernel and
208drivers.
209
210Requirements for KMS UAPI
211-------------------------
212
213- KMS connectors must change their status to disconnected.
214
215- Legacy modesets and pageflips, and atomic commits, both real and
216 TEST_ONLY, and any other ioctls either fail with ENODEV or fake
217 success.
218
219- Pending non-blocking KMS operations deliver the DRM events userspace
220 is expecting. This applies also to ioctls that faked success.
221
222- open() on a device node whose underlying device has disappeared will
223 fail with ENXIO.
224
225- Attempting to create a DRM lease on a disappeared DRM device will
226 fail with ENODEV. Existing DRM leases remain and work as listed
227 above.
228
229Requirements for Render and Cross-Device UAPI
230---------------------------------------------
231
232- All GPU jobs that can no longer run must have their fences
233 force-signalled to avoid inflicting hangs on userspace.
234 The associated error code is ENODEV.
235
236- Some userspace APIs already define what should happen when the device
237 disappears (OpenGL, GL ES: `GL_KHR_robustness`_; `Vulkan`_:
238 VK_ERROR_DEVICE_LOST; etc.). DRM drivers are free to implement this
239 behaviour the way they see best, e.g. returning failures in
240 driver-specific ioctls and handling those in userspace drivers, or
241 rely on uevents, and so on.
242
243- dmabuf which point to memory that has disappeared will either fail to
244 import with ENODEV or continue to be successfully imported if it would
245 have succeeded before the disappearance. See also about memory maps
246 below for already imported dmabufs.
247
248- Attempting to import a dmabuf to a disappeared device will either fail
249 with ENODEV or succeed if it would have succeeded without the
250 disappearance.
251
252- open() on a device node whose underlying device has disappeared will
253 fail with ENXIO.
254
255.. _GL_KHR_robustness: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_robustness.txt
256.. _Vulkan: https://www.khronos.org/vulkan/
257
258Requirements for Memory Maps
259----------------------------
260
261Memory maps have further requirements that apply to both existing maps
262and maps created after the device has disappeared. If the underlying
263memory disappears, the map is created or modified such that reads and
264writes will still complete successfully but the result is undefined.
265This applies to both userspace mmap()'d memory and memory pointed to by
266dmabuf which might be mapped to other devices (cross-device dmabuf
267imports).
268
269Raising SIGBUS is not an option, because userspace cannot realistically
270handle it. Signal handlers are global, which makes them extremely
271difficult to use correctly from libraries like those that Mesa produces.
272Signal handlers are not composable, you can't have different handlers
273for GPU1 and GPU2 from different vendors, and a third handler for
274mmapped regular files. Threads cause additional pain with signal
275handling as well.
276
165.. _drm_driver_ioctl:277.. _drm_driver_ioctl:
166 278
167IOCTL Support on Device Nodes279IOCTL Support on Device Nodes
@@ -199,7 +311,7 @@ EPERM/EACCES: · 31 unmodified lines
199 difference between EACCES and EPERM.311 difference between EACCES and EPERM.
200 312
201ENODEV:313ENODEV:
202 The device is not (yet) present or fully initialized.314 The device is not present anymore or is not yet fully initialized.
203 315
204EOPNOTSUPP:316EOPNOTSUPP:
205 Feature (like PRIME, modesetting, GEM) is not supported by the driver.317 Feature (like PRIME, modesetting, GEM) is not supported by the driver.
Documentation/gpu/pl111.rst+4−4
@@ -1,6 +1,6 @@
1==========================================1====================================================
2 drm/pl111 ARM PrimeCell PL111 CLCD Driver2 drm/pl111 ARM PrimeCell PL110 and PL111 CLCD Driver
3==========================================3====================================================
4 4
5.. kernel-doc:: drivers/gpu/drm/pl111/pl111_drv.c5.. kernel-doc:: drivers/gpu/drm/pl111/pl111_drv.c
6 :doc: ARM PrimeCell PL111 CLCD Driver6 :doc: ARM PrimeCell PL110 and PL111 CLCD Driver
Documentation/gpu/todo.rst+46−0
@@ -403,6 +403,52 @@ Contact: Emil Velikov, respective driver maintainers · 402 unmodified lines
403 403
404Level: Intermediate404Level: Intermediate
405 405
406Plumb drm_atomic_state all over
407-------------------------------
408
409Currently various atomic functions take just a single or a handful of
410object states (eg. plane state). While that single object state can
411suffice for some simple cases, we often have to dig out additional
412object states for dealing with various dependencies between the individual
413objects or the hardware they represent. The process of digging out the
414additional states is rather non-intuitive and error prone.
415
416To fix that most functions should rather take the overall
417drm_atomic_state as one of their parameters. The other parameters
418would generally be the object(s) we mainly want to interact with.
419
420For example, instead of
421
422.. code-block:: c
423
424 int (*atomic_check)(struct drm_plane *plane, struct drm_plane_state *state);
425
426we would have something like
427
428.. code-block:: c
429
430 int (*atomic_check)(struct drm_plane *plane, struct drm_atomic_state *state);
431
432The implementation can then trivially gain access to any required object
433state(s) via drm_atomic_get_plane_state(), drm_atomic_get_new_plane_state(),
434drm_atomic_get_old_plane_state(), and their equivalents for
435other object types.
436
437Additionally many drivers currently access the object->state pointer
438directly in their commit functions. That is not going to work if we
439eg. want to allow deeper commit pipelines as those pointers could
440then point to the states corresponding to a future commit instead of
441the current commit we're trying to process. Also non-blocking commits
442execute locklessly so there are serious concerns with dereferencing
443the object->state pointers without holding the locks that protect them.
444Use of drm_atomic_get_new_plane_state(), drm_atomic_get_old_plane_state(),
445etc. avoids these problems as well since they relate to a specific
446commit via the passed in drm_atomic_state.
447
448Contact: Ville Syrjälä, Daniel Vetter
449
450Level: Intermediate
451
406 452
407Core refactorings453Core refactorings
408=================454=================
MAINTAINERS+9−2
@@ -5474,12 +5474,19 @@ S: Maintained · 5473 unmodified lines
5474F: drivers/gpu/drm/panel/panel-lvds.c5474F: drivers/gpu/drm/panel/panel-lvds.c
5475F: Documentation/devicetree/bindings/display/panel/lvds.yaml5475F: Documentation/devicetree/bindings/display/panel/lvds.yaml
5476 5476
5477DRM DRIVER FOR MANTIX MLAF057WE51 PANELS
5478M: Guido Günther <agx@sigxcpu.org>
5479R: Purism Kernel Team <kernel@puri.sm>
5480S: Maintained
5481F: Documentation/devicetree/bindings/display/panel/mantix,mlaf057we51-x.yaml
5482F: drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c
5483
5477DRM DRIVER FOR MATROX G200/G400 GRAPHICS CARDS5484DRM DRIVER FOR MATROX G200/G400 GRAPHICS CARDS
5478S: Orphan / Obsolete5485S: Orphan / Obsolete
5479F: drivers/gpu/drm/mga/5486F: drivers/gpu/drm/mga/
5480F: include/uapi/drm/mga_drm.h5487F: include/uapi/drm/mga_drm.h
5481 5488
5482DRM DRIVER FOR MGA G200 SERVER GRAPHICS CHIPS5489DRM DRIVER FOR MGA G200 GRAPHICS CHIPS
5483M: Dave Airlie <airlied@redhat.com>5490M: Dave Airlie <airlied@redhat.com>
5484S: Odd Fixes5491S: Odd Fixes
5485F: drivers/gpu/drm/mgag200/5492F: drivers/gpu/drm/mgag200/
@@ -5767,7 +5774,7 @@ F: drivers/gpu/drm/gma500/ · 281 unmodified lines
5767 5774
5768DRM DRIVERS FOR HISILICON5775DRM DRIVERS FOR HISILICON
5769M: Xinliang Liu <xinliang.liu@linaro.org>5776M: Xinliang Liu <xinliang.liu@linaro.org>
5770M: Rongrong Zou <zourongrong@gmail.com>5777M: Tian Tao <tiantao6@hisilicon.com>
5771R: John Stultz <john.stultz@linaro.org>5778R: John Stultz <john.stultz@linaro.org>
5772R: Xinwei Kong <kong.kongxinwei@hisilicon.com>5779R: Xinwei Kong <kong.kongxinwei@hisilicon.com>
5773R: Chen Feng <puck.chen@hisilicon.com>5780R: Chen Feng <puck.chen@hisilicon.com>
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.c+2−1
@@ -517,8 +517,9 @@ out_put: · 516 unmodified lines
517uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)517uint64_t amdgpu_amdkfd_get_vram_usage(struct kgd_dev *kgd)
518{518{
519 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;519 struct amdgpu_device *adev = (struct amdgpu_device *)kgd;
520 struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
520 521
521 return amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);522 return amdgpu_vram_mgr_usage(vram_man);
522}523}
523 524
524uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd)525uint64_t amdgpu_amdkfd_get_hive_id(struct kgd_dev *kgd)
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c+1−1
@@ -562,7 +562,7 @@ static int init_user_pages(struct kgd_mem *mem, uint64_t user_addr) · 561 unmodified lines
562 562
563 mutex_lock(&process_info->lock);563 mutex_lock(&process_info->lock);
564 564
565 ret = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, user_addr, 0);565 ret = amdgpu_ttm_tt_set_userptr(&bo->tbo, user_addr, 0);
566 if (ret) {566 if (ret) {
567 pr_err("%s: Failed to set userptr: %d\n", __func__, ret);567 pr_err("%s: Failed to set userptr: %d\n", __func__, ret);
568 goto out;568 goto out;
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c+10−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
26 26
27#include <drm/drm_edid.h>27#include <drm/drm_edid.h>
28#include <drm/drm_fb_helper.h>28#include <drm/drm_fb_helper.h>
29#include <drm/drm_dp_helper.h>
29#include <drm/drm_probe_helper.h>30#include <drm/drm_probe_helper.h>
30#include <drm/amdgpu_drm.h>31#include <drm/amdgpu_drm.h>
31#include "amdgpu.h"32#include "amdgpu.h"
@@ -1413,6 +1414,10 @@ out: · 1381 unmodified lines
1413 pm_runtime_put_autosuspend(connector->dev->dev);1414 pm_runtime_put_autosuspend(connector->dev->dev);
1414 }1415 }
1415 1416
1417 drm_dp_set_subconnector_property(&amdgpu_connector->base,
1418 ret,
1419 amdgpu_dig_connector->dpcd,
1420 amdgpu_dig_connector->downstream_ports);
1416 return ret;1421 return ret;
1417}1422}
1418 1423
@@ -1959,6 +1964,11 @@ amdgpu_connector_add(struct amdgpu_device *adev, · 540 unmodified lines
1959 if (has_aux)1964 if (has_aux)
1960 amdgpu_atombios_dp_aux_init(amdgpu_connector);1965 amdgpu_atombios_dp_aux_init(amdgpu_connector);
1961 1966
1967 if (connector_type == DRM_MODE_CONNECTOR_DisplayPort ||
1968 connector_type == DRM_MODE_CONNECTOR_eDP) {
1969 drm_connector_attach_dp_subconnector_property(&amdgpu_connector->base);
1970 }
1971
1962 return;1972 return;
1963 1973
1964failed:1974failed:
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c+3−3
@@ -299,7 +299,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, · 298 unmodified lines
299{299{
300 s64 time_us, increment_us;300 s64 time_us, increment_us;
301 u64 free_vram, total_vram, used_vram;301 u64 free_vram, total_vram, used_vram;
302 302 struct ttm_resource_manager *vram_man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
303 /* Allow a maximum of 200 accumulated ms. This is basically per-IB303 /* Allow a maximum of 200 accumulated ms. This is basically per-IB
304 * throttling.304 * throttling.
305 *305 *
@@ -316,7 +316,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, · 10 unmodified lines
316 }316 }
317 317
318 total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size);318 total_vram = adev->gmc.real_vram_size - atomic64_read(&adev->vram_pin_size);
319 used_vram = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);319 used_vram = amdgpu_vram_mgr_usage(vram_man);
320 free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;320 free_vram = used_vram >= total_vram ? 0 : total_vram - used_vram;
321 321
322 spin_lock(&adev->mm_stats.lock);322 spin_lock(&adev->mm_stats.lock);
@@ -363,7 +363,7 @@ static void amdgpu_cs_get_threshold_for_moves(struct amdgpu_device *adev, · 40 unmodified lines
363 if (!amdgpu_gmc_vram_full_visible(&adev->gmc)) {363 if (!amdgpu_gmc_vram_full_visible(&adev->gmc)) {
364 u64 total_vis_vram = adev->gmc.visible_vram_size;364 u64 total_vis_vram = adev->gmc.visible_vram_size;
365 u64 used_vis_vram =365 u64 used_vis_vram =
366 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);366 amdgpu_vram_mgr_vis_usage(vram_man);
367 367
368 if (used_vis_vram < total_vis_vram) {368 if (used_vis_vram < total_vis_vram) {
369 u64 free_vis_vram = total_vis_vram - used_vis_vram;369 u64 free_vis_vram = total_vis_vram - used_vis_vram;
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+2−3
@@ -3882,7 +3882,7 @@ static int amdgpu_device_reset_sriov(struct amdgpu_device *adev, · 3881 unmodified lines
3882 3882
3883 amdgpu_virt_init_data_exchange(adev);3883 amdgpu_virt_init_data_exchange(adev);
3884 /* we need recover gart prior to run SMC/CP/SDMA resume */3884 /* we need recover gart prior to run SMC/CP/SDMA resume */
3885 amdgpu_gtt_mgr_recover(&adev->mman.bdev.man[TTM_PL_TT]);3885 amdgpu_gtt_mgr_recover(ttm_manager_type(&adev->mman.bdev, TTM_PL_TT));
3886 3886
3887 r = amdgpu_device_fw_loading(adev);3887 r = amdgpu_device_fw_loading(adev);
3888 if (r)3888 if (r)
@@ -4081,8 +4081,7 @@ static int amdgpu_do_asic_reset(struct amdgpu_hive_info *hive, · 192 unmodified lines
4081 amdgpu_inc_vram_lost(tmp_adev);4081 amdgpu_inc_vram_lost(tmp_adev);
4082 }4082 }
4083 4083
4084 r = amdgpu_gtt_mgr_recover(4084 r = amdgpu_gtt_mgr_recover(ttm_manager_type(&tmp_adev->mman.bdev, TTM_PL_TT));
4085 &tmp_adev->mman.bdev.man[TTM_PL_TT]);
4086 if (r)4085 if (r)
4087 goto out;4086 goto out;
4088 4087
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c+2−2
@@ -393,12 +393,12 @@ MODULE_PARM_DESC(sched_hw_submission, "the max number of HW submissions (default · 392 unmodified lines
393module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444);393module_param_named(sched_hw_submission, amdgpu_sched_hw_submission, int, 0444);
394 394
395/**395/**
396 * DOC: ppfeaturemask (uint)396 * DOC: ppfeaturemask (hexint)
397 * Override power features enabled. See enum PP_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h.397 * Override power features enabled. See enum PP_FEATURE_MASK in drivers/gpu/drm/amd/include/amd_shared.h.
398 * The default is the current set of stable power features.398 * The default is the current set of stable power features.
399 */399 */
400MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");400MODULE_PARM_DESC(ppfeaturemask, "all power features enabled (default))");
401module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, uint, 0444);401module_param_named(ppfeaturemask, amdgpu_pp_feature_mask, hexint, 0444);
402 402
403/**403/**
404 * DOC: forcelongtraining (uint)404 * DOC: forcelongtraining (uint)
drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c+1−1
@@ -332,7 +332,7 @@ int amdgpu_gem_userptr_ioctl(struct drm_device *dev, void *data, · 331 unmodified lines
332 bo = gem_to_amdgpu_bo(gobj);332 bo = gem_to_amdgpu_bo(gobj);
333 bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;333 bo->preferred_domains = AMDGPU_GEM_DOMAIN_GTT;
334 bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;334 bo->allowed_domains = AMDGPU_GEM_DOMAIN_GTT;
335 r = amdgpu_ttm_tt_set_userptr(bo->tbo.ttm, args->addr, args->flags);335 r = amdgpu_ttm_tt_set_userptr(&bo->tbo, args->addr, args->flags);
336 if (r)336 if (r)
337 goto release_object;337 goto release_object;
338 338
drivers/gpu/drm/amd/amdgpu/amdgpu_gtt_mgr.c+50−42
@@ -24,11 +24,10 @@ · 23 unmodified lines
24 24
25#include "amdgpu.h"25#include "amdgpu.h"
26 26
27struct amdgpu_gtt_mgr {27static inline struct amdgpu_gtt_mgr *to_gtt_mgr(struct ttm_resource_manager *man)
28 struct drm_mm mm;28{
29 spinlock_t lock;29 return container_of(man, struct amdgpu_gtt_mgr, manager);
30 atomic64_t available;30}
31};
32 31
33struct amdgpu_gtt_node {32struct amdgpu_gtt_node {
34 struct drm_mm_node node;33 struct drm_mm_node node;
@@ -48,9 +47,9 @@ static ssize_t amdgpu_mem_info_gtt_total_show(struct device *dev, · 13 unmodified lines
48{47{
49 struct drm_device *ddev = dev_get_drvdata(dev);48 struct drm_device *ddev = dev_get_drvdata(dev);
50 struct amdgpu_device *adev = ddev->dev_private;49 struct amdgpu_device *adev = ddev->dev_private;
51 50 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
52 return snprintf(buf, PAGE_SIZE, "%llu\n",51 return snprintf(buf, PAGE_SIZE, "%llu\n",
53 (adev->mman.bdev.man[TTM_PL_TT].size) * PAGE_SIZE);52 man->size * PAGE_SIZE);
54}53}
55 54
56/**55/**
@@ -66,9 +65,9 @@ static ssize_t amdgpu_mem_info_gtt_used_show(struct device *dev, · 9 unmodified lines
66{65{
67 struct drm_device *ddev = dev_get_drvdata(dev);66 struct drm_device *ddev = dev_get_drvdata(dev);
68 struct amdgpu_device *adev = ddev->dev_private;67 struct amdgpu_device *adev = ddev->dev_private;
69 68 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
70 return snprintf(buf, PAGE_SIZE, "%llu\n",69 return snprintf(buf, PAGE_SIZE, "%llu\n",
71 amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]));70 amdgpu_gtt_mgr_usage(man));
72}71}
73 72
74static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,73static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO,
@@ -76,6 +75,7 @@ static DEVICE_ATTR(mem_info_gtt_total, S_IRUGO, · 1 unmodified line
76static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,75static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO,
77 amdgpu_mem_info_gtt_used_show, NULL);76 amdgpu_mem_info_gtt_used_show, NULL);
78 77
78static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func;
79/**79/**
80 * amdgpu_gtt_mgr_init - init GTT manager and DRM MM80 * amdgpu_gtt_mgr_init - init GTT manager and DRM MM
81 *81 *
@@ -84,24 +84,25 @@ static DEVICE_ATTR(mem_info_gtt_used, S_IRUGO, · 2 unmodified lines
84 *84 *
85 * Allocate and initialize the GTT manager.85 * Allocate and initialize the GTT manager.
86 */86 */
87static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man,87int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size)
88 unsigned long p_size)
89{88{
90 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);89 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
91 struct amdgpu_gtt_mgr *mgr;90 struct ttm_resource_manager *man = &mgr->manager;
92 uint64_t start, size;91 uint64_t start, size;
93 int ret;92 int ret;
94 93
95 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);94 man->use_tt = true;
96 if (!mgr)95 man->func = &amdgpu_gtt_mgr_func;
97 return -ENOMEM;96 man->available_caching = TTM_PL_MASK_CACHING;
97 man->default_caching = TTM_PL_FLAG_CACHED;
98
99 ttm_resource_manager_init(man, gtt_size >> PAGE_SHIFT);
98 100
99 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;101 start = AMDGPU_GTT_MAX_TRANSFER_SIZE * AMDGPU_GTT_NUM_TRANSFER_WINDOWS;
100 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;102 size = (adev->gmc.gart_size >> PAGE_SHIFT) - start;
101 drm_mm_init(&mgr->mm, start, size);103 drm_mm_init(&mgr->mm, start, size);
102 spin_lock_init(&mgr->lock);104 spin_lock_init(&mgr->lock);
103 atomic64_set(&mgr->available, p_size);105 atomic64_set(&mgr->available, gtt_size >> PAGE_SHIFT);
104 man->priv = mgr;
105 106
106 ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_total);107 ret = device_create_file(adev->dev, &dev_attr_mem_info_gtt_total);
107 if (ret) {108 if (ret) {
@@ -114,6 +115,8 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man, · 6 unmodified lines
114 return ret;115 return ret;
115 }116 }
116 117
118 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, &mgr->manager);
119 ttm_resource_manager_set_used(man, true);
117 return 0;120 return 0;
118}121}
119 122
@@ -125,20 +128,27 @@ static int amdgpu_gtt_mgr_init(struct ttm_mem_type_manager *man, · 5 unmodified lines
125 * Destroy and free the GTT manager, returns -EBUSY if ranges are still128 * Destroy and free the GTT manager, returns -EBUSY if ranges are still
126 * allocated inside it.129 * allocated inside it.
127 */130 */
128static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man)131void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev)
129{132{
130 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);133 struct amdgpu_gtt_mgr *mgr = &adev->mman.gtt_mgr;
131 struct amdgpu_gtt_mgr *mgr = man->priv;134 struct ttm_resource_manager *man = &mgr->manager;
135 int ret;
136
137 ttm_resource_manager_set_used(man, false);
138
139 ret = ttm_resource_manager_force_list_clean(&adev->mman.bdev, man);
140 if (ret)
141 return;
142
132 spin_lock(&mgr->lock);143 spin_lock(&mgr->lock);
133 drm_mm_takedown(&mgr->mm);144 drm_mm_takedown(&mgr->mm);
134 spin_unlock(&mgr->lock);145 spin_unlock(&mgr->lock);
135 kfree(mgr);
136 man->priv = NULL;
137 146
138 device_remove_file(adev->dev, &dev_attr_mem_info_gtt_total);147 device_remove_file(adev->dev, &dev_attr_mem_info_gtt_total);
139 device_remove_file(adev->dev, &dev_attr_mem_info_gtt_used);148 device_remove_file(adev->dev, &dev_attr_mem_info_gtt_used);
140 149
141 return 0;150 ttm_resource_manager_cleanup(man);
151 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_TT, NULL);
142}152}
143 153
144/**154/**
@@ -148,7 +158,7 @@ static int amdgpu_gtt_mgr_fini(struct ttm_mem_type_manager *man) · 3 unmodified lines
148 *158 *
149 * Check if a mem object has already address space allocated.159 * Check if a mem object has already address space allocated.
150 */160 */
151bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem)161bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem)
152{162{
153 return mem->mm_node != NULL;163 return mem->mm_node != NULL;
154}164}
@@ -163,12 +173,12 @@ bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem) · 8 unmodified lines
163 *173 *
164 * Dummy, allocate the node but no space for it yet.174 * Dummy, allocate the node but no space for it yet.
165 */175 */
166static int amdgpu_gtt_mgr_new(struct ttm_mem_type_manager *man,176static int amdgpu_gtt_mgr_new(struct ttm_resource_manager *man,
167 struct ttm_buffer_object *tbo,177 struct ttm_buffer_object *tbo,
168 const struct ttm_place *place,178 const struct ttm_place *place,
169 struct ttm_mem_reg *mem)179 struct ttm_resource *mem)
170{180{
171 struct amdgpu_gtt_mgr *mgr = man->priv;181 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
172 struct amdgpu_gtt_node *node;182 struct amdgpu_gtt_node *node;
173 int r;183 int r;
174 184
@@ -226,10 +236,10 @@ err_out: · 51 unmodified lines
226 *236 *
227 * Free the allocated GTT again.237 * Free the allocated GTT again.
228 */238 */
229static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man,239static void amdgpu_gtt_mgr_del(struct ttm_resource_manager *man,
230 struct ttm_mem_reg *mem)240 struct ttm_resource *mem)
231{241{
232 struct amdgpu_gtt_mgr *mgr = man->priv;242 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
233 struct amdgpu_gtt_node *node = mem->mm_node;243 struct amdgpu_gtt_node *node = mem->mm_node;
234 244
235 if (node) {245 if (node) {
@@ -249,17 +259,17 @@ static void amdgpu_gtt_mgr_del(struct ttm_mem_type_manager *man, · 13 unmodified lines
249 *259 *
250 * Return how many bytes are used in the GTT domain260 * Return how many bytes are used in the GTT domain
251 */261 */
252uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man)262uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man)
253{263{
254 struct amdgpu_gtt_mgr *mgr = man->priv;264 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
255 s64 result = man->size - atomic64_read(&mgr->available);265 s64 result = man->size - atomic64_read(&mgr->available);
256 266
257 return (result > 0 ? result : 0) * PAGE_SIZE;267 return (result > 0 ? result : 0) * PAGE_SIZE;
258}268}
259 269
260int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man)270int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man)
261{271{
262 struct amdgpu_gtt_mgr *mgr = man->priv;272 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
263 struct amdgpu_gtt_node *node;273 struct amdgpu_gtt_node *node;
264 struct drm_mm_node *mm_node;274 struct drm_mm_node *mm_node;
265 int r = 0;275 int r = 0;
@@ -284,10 +294,10 @@ int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man) · 18 unmodified lines
284 *294 *
285 * Dump the table content using printk.295 * Dump the table content using printk.
286 */296 */
287static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man,297static void amdgpu_gtt_mgr_debug(struct ttm_resource_manager *man,
288 struct drm_printer *printer)298 struct drm_printer *printer)
289{299{
290 struct amdgpu_gtt_mgr *mgr = man->priv;300 struct amdgpu_gtt_mgr *mgr = to_gtt_mgr(man);
291 301
292 spin_lock(&mgr->lock);302 spin_lock(&mgr->lock);
293 drm_mm_print(&mgr->mm, printer);303 drm_mm_print(&mgr->mm, printer);
@@ -298,10 +308,8 @@ static void amdgpu_gtt_mgr_debug(struct ttm_mem_type_manager *man, · 4 unmodified lines
298 amdgpu_gtt_mgr_usage(man) >> 20);308 amdgpu_gtt_mgr_usage(man) >> 20);
299}309}
300 310
301const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func = {311static const struct ttm_resource_manager_func amdgpu_gtt_mgr_func = {
302 .init = amdgpu_gtt_mgr_init,312 .alloc = amdgpu_gtt_mgr_new,
303 .takedown = amdgpu_gtt_mgr_fini,313 .free = amdgpu_gtt_mgr_del,
304 .get_node = amdgpu_gtt_mgr_new,
305 .put_node = amdgpu_gtt_mgr_del,
306 .debug = amdgpu_gtt_mgr_debug314 .debug = amdgpu_gtt_mgr_debug
307};315};
drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c+12−9
@@ -594,13 +594,13 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file · 593 unmodified lines
594 ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);594 ui64 = atomic64_read(&adev->num_vram_cpu_page_faults);
595 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;595 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
596 case AMDGPU_INFO_VRAM_USAGE:596 case AMDGPU_INFO_VRAM_USAGE:
597 ui64 = amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);597 ui64 = amdgpu_vram_mgr_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM));
598 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;598 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
599 case AMDGPU_INFO_VIS_VRAM_USAGE:599 case AMDGPU_INFO_VIS_VRAM_USAGE:
600 ui64 = amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);600 ui64 = amdgpu_vram_mgr_vis_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM));
601 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;601 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
602 case AMDGPU_INFO_GTT_USAGE:602 case AMDGPU_INFO_GTT_USAGE:
603 ui64 = amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);603 ui64 = amdgpu_gtt_mgr_usage(ttm_manager_type(&adev->mman.bdev, TTM_PL_TT));
604 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;604 return copy_to_user(out, &ui64, min(size, 8u)) ? -EFAULT : 0;
605 case AMDGPU_INFO_GDS_CONFIG: {605 case AMDGPU_INFO_GDS_CONFIG: {
606 struct drm_amdgpu_info_gds gds_info;606 struct drm_amdgpu_info_gds gds_info;
@@ -623,7 +623,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file · 16 unmodified lines
623 min(adev->gmc.visible_vram_size -623 min(adev->gmc.visible_vram_size -
624 atomic64_read(&adev->visible_pin_size),624 atomic64_read(&adev->visible_pin_size),
625 vram_gtt.vram_size);625 vram_gtt.vram_size);
626 vram_gtt.gtt_size = adev->mman.bdev.man[TTM_PL_TT].size;626 vram_gtt.gtt_size = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT)->size;
627 vram_gtt.gtt_size *= PAGE_SIZE;627 vram_gtt.gtt_size *= PAGE_SIZE;
628 vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size);628 vram_gtt.gtt_size -= atomic64_read(&adev->gart_pin_size);
629 return copy_to_user(out, &vram_gtt,629 return copy_to_user(out, &vram_gtt,
@@ -631,14 +631,17 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file · 1 unmodified line
631 }631 }
632 case AMDGPU_INFO_MEMORY: {632 case AMDGPU_INFO_MEMORY: {
633 struct drm_amdgpu_memory_info mem;633 struct drm_amdgpu_memory_info mem;
634 634 struct ttm_resource_manager *vram_man =
635 ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
636 struct ttm_resource_manager *gtt_man =
637 ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
635 memset(&mem, 0, sizeof(mem));638 memset(&mem, 0, sizeof(mem));
636 mem.vram.total_heap_size = adev->gmc.real_vram_size;639 mem.vram.total_heap_size = adev->gmc.real_vram_size;
637 mem.vram.usable_heap_size = adev->gmc.real_vram_size -640 mem.vram.usable_heap_size = adev->gmc.real_vram_size -
638 atomic64_read(&adev->vram_pin_size) -641 atomic64_read(&adev->vram_pin_size) -
639 AMDGPU_VM_RESERVED_VRAM;642 AMDGPU_VM_RESERVED_VRAM;
640 mem.vram.heap_usage =643 mem.vram.heap_usage =
641 amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);644 amdgpu_vram_mgr_usage(vram_man);
642 mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;645 mem.vram.max_allocation = mem.vram.usable_heap_size * 3 / 4;
643 646
644 mem.cpu_accessible_vram.total_heap_size =647 mem.cpu_accessible_vram.total_heap_size =
@@ -648,16 +651,16 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file · 3 unmodified lines
648 atomic64_read(&adev->visible_pin_size),651 atomic64_read(&adev->visible_pin_size),
649 mem.vram.usable_heap_size);652 mem.vram.usable_heap_size);
650 mem.cpu_accessible_vram.heap_usage =653 mem.cpu_accessible_vram.heap_usage =
651 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]);654 amdgpu_vram_mgr_vis_usage(vram_man);
652 mem.cpu_accessible_vram.max_allocation =655 mem.cpu_accessible_vram.max_allocation =
653 mem.cpu_accessible_vram.usable_heap_size * 3 / 4;656 mem.cpu_accessible_vram.usable_heap_size * 3 / 4;
654 657
655 mem.gtt.total_heap_size = adev->mman.bdev.man[TTM_PL_TT].size;658 mem.gtt.total_heap_size = gtt_man->size;
656 mem.gtt.total_heap_size *= PAGE_SIZE;659 mem.gtt.total_heap_size *= PAGE_SIZE;
657 mem.gtt.usable_heap_size = mem.gtt.total_heap_size -660 mem.gtt.usable_heap_size = mem.gtt.total_heap_size -
658 atomic64_read(&adev->gart_pin_size);661 atomic64_read(&adev->gart_pin_size);
659 mem.gtt.heap_usage =662 mem.gtt.heap_usage =
660 amdgpu_gtt_mgr_usage(&adev->mman.bdev.man[TTM_PL_TT]);663 amdgpu_gtt_mgr_usage(gtt_man);
661 mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;664 mem.gtt.max_allocation = mem.gtt.usable_heap_size * 3 / 4;
662 665
663 return copy_to_user(out, &mem,666 return copy_to_user(out, &mem,
drivers/gpu/drm/amd/amdgpu/amdgpu_mode.h+1−0
@@ -469,6 +469,7 @@ struct amdgpu_encoder { · 468 unmodified lines
469struct amdgpu_connector_atom_dig {469struct amdgpu_connector_atom_dig {
470 /* displayport */470 /* displayport */
471 u8 dpcd[DP_RECEIVER_CAP_SIZE];471 u8 dpcd[DP_RECEIVER_CAP_SIZE];
472 u8 downstream_ports[DP_MAX_DOWNSTREAM_PORTS];
472 u8 dp_sink_type;473 u8 dp_sink_type;
473 int dp_clock;474 int dp_clock;
474 int dp_lane_count;475 int dp_lane_count;
drivers/gpu/drm/amd/amdgpu/amdgpu_object.c+6−6
@@ -381,7 +381,7 @@ int amdgpu_bo_create_kernel_at(struct amdgpu_device *adev, · 380 unmodified lines
381 if (cpu_addr)381 if (cpu_addr)
382 amdgpu_bo_kunmap(*bo_ptr);382 amdgpu_bo_kunmap(*bo_ptr);
383 383
384 ttm_bo_mem_put(&(*bo_ptr)->tbo, &(*bo_ptr)->tbo.mem);384 ttm_resource_free(&(*bo_ptr)->tbo, &(*bo_ptr)->tbo.mem);
385 385
386 for (i = 0; i < (*bo_ptr)->placement.num_placement; ++i) {386 for (i = 0; i < (*bo_ptr)->placement.num_placement; ++i) {
387 (*bo_ptr)->placements[i].fpfn = offset >> PAGE_SHIFT;387 (*bo_ptr)->placements[i].fpfn = offset >> PAGE_SHIFT;
@@ -442,14 +442,14 @@ void amdgpu_bo_free_kernel(struct amdgpu_bo **bo, u64 *gpu_addr, · 54 unmodified lines
442static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,442static bool amdgpu_bo_validate_size(struct amdgpu_device *adev,
443 unsigned long size, u32 domain)443 unsigned long size, u32 domain)
444{444{
445 struct ttm_mem_type_manager *man = NULL;445 struct ttm_resource_manager *man = NULL;
446 446
447 /*447 /*
448 * If GTT is part of requested domains the check must succeed to448 * If GTT is part of requested domains the check must succeed to
449 * allow fall back to GTT449 * allow fall back to GTT
450 */450 */
451 if (domain & AMDGPU_GEM_DOMAIN_GTT) {451 if (domain & AMDGPU_GEM_DOMAIN_GTT) {
452 man = &adev->mman.bdev.man[TTM_PL_TT];452 man = ttm_manager_type(&adev->mman.bdev, TTM_PL_TT);
453 453
454 if (size < (man->size << PAGE_SHIFT))454 if (size < (man->size << PAGE_SHIFT))
455 return true;455 return true;
@@ -458,7 +458,7 @@ static bool amdgpu_bo_validate_size(struct amdgpu_device *adev, · 2 unmodified lines
458 }458 }
459 459
460 if (domain & AMDGPU_GEM_DOMAIN_VRAM) {460 if (domain & AMDGPU_GEM_DOMAIN_VRAM) {
461 man = &adev->mman.bdev.man[TTM_PL_VRAM];461 man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
462 462
463 if (size < (man->size << PAGE_SHIFT))463 if (size < (man->size << PAGE_SHIFT))
464 return true;464 return true;
@@ -1268,11 +1268,11 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, · 803 unmodified lines
1268 */1268 */
1269void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,1269void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
1270 bool evict,1270 bool evict,
1271 struct ttm_mem_reg *new_mem)1271 struct ttm_resource *new_mem)
1272{1272{
1273 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);1273 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
1274 struct amdgpu_bo *abo;1274 struct amdgpu_bo *abo;
1275 struct ttm_mem_reg *old_mem = &bo->mem;1275 struct ttm_resource *old_mem = &bo->mem;
1276 1276
1277 if (!amdgpu_bo_is_amdgpu_bo(bo))1277 if (!amdgpu_bo_is_amdgpu_bo(bo))
1278 return;1278 return;
drivers/gpu/drm/amd/amdgpu/amdgpu_object.h+2−2
@@ -160,7 +160,7 @@ static inline int amdgpu_bo_reserve(struct amdgpu_bo *bo, bool no_intr) · 159 unmodified lines
160 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);160 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
161 int r;161 int r;
162 162
163 r = __ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL);163 r = ttm_bo_reserve(&bo->tbo, !no_intr, false, NULL);
164 if (unlikely(r != 0)) {164 if (unlikely(r != 0)) {
165 if (r != -ERESTARTSYS)165 if (r != -ERESTARTSYS)
166 dev_err(adev->dev, "%p reserve failed\n", bo);166 dev_err(adev->dev, "%p reserve failed\n", bo);
@@ -283,7 +283,7 @@ int amdgpu_bo_get_metadata(struct amdgpu_bo *bo, void *buffer, · 116 unmodified lines
283 uint64_t *flags);283 uint64_t *flags);
284void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,284void amdgpu_bo_move_notify(struct ttm_buffer_object *bo,
285 bool evict,285 bool evict,
286 struct ttm_mem_reg *new_mem);286 struct ttm_resource *new_mem);
287void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);287void amdgpu_bo_release_notify(struct ttm_buffer_object *bo);
288int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);288int amdgpu_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
289void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,289void amdgpu_bo_fence(struct amdgpu_bo *bo, struct dma_fence *fence,
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c+58−113
@@ -63,61 +63,13 @@ · 62 unmodified lines
63 63
64#define AMDGPU_TTM_VRAM_MAX_DW_READ (size_t)12864#define AMDGPU_TTM_VRAM_MAX_DW_READ (size_t)128
65 65
66 66static int amdgpu_ttm_init_on_chip(struct amdgpu_device *adev,
67/**67 unsigned int type,
68 * amdgpu_init_mem_type - Initialize a memory manager for a specific type of68 uint64_t size)
69 * memory request.
70 *
71 * @bdev: The TTM BO device object (contains a reference to amdgpu_device)
72 * @type: The type of memory requested
73 * @man: The memory type manager for each domain
74 *
75 * This is called by ttm_bo_init_mm() when a buffer object is being
76 * initialized.
77 */
78static int amdgpu_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
79 struct ttm_mem_type_manager *man)
80{69{
81 struct amdgpu_device *adev;70 return ttm_range_man_init(&adev->mman.bdev, type,
82 71 TTM_PL_FLAG_UNCACHED, TTM_PL_FLAG_UNCACHED,
83 adev = amdgpu_ttm_adev(bdev);72 false, size >> PAGE_SHIFT);
84
85 switch (type) {
86 case TTM_PL_SYSTEM:
87 /* System memory */
88 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
89 man->available_caching = TTM_PL_MASK_CACHING;
90 man->default_caching = TTM_PL_FLAG_CACHED;
91 break;
92 case TTM_PL_TT:
93 /* GTT memory */
94 man->func = &amdgpu_gtt_mgr_func;
95 man->available_caching = TTM_PL_MASK_CACHING;
96 man->default_caching = TTM_PL_FLAG_CACHED;
97 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
98 break;
99 case TTM_PL_VRAM:
100 /* "On-card" video ram */
101 man->func = &amdgpu_vram_mgr_func;
102 man->flags = TTM_MEMTYPE_FLAG_FIXED |
103 TTM_MEMTYPE_FLAG_MAPPABLE;
104 man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
105 man->default_caching = TTM_PL_FLAG_WC;
106 break;
107 case AMDGPU_PL_GDS:
108 case AMDGPU_PL_GWS:
109 case AMDGPU_PL_OA:
110 /* On-chip GDS memory*/
111 man->func = &ttm_bo_manager_func;
112 man->flags = TTM_MEMTYPE_FLAG_FIXED;
113 man->available_caching = TTM_PL_FLAG_UNCACHED;
114 man->default_caching = TTM_PL_FLAG_UNCACHED;
115 break;
116 default:
117 DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
118 return -EINVAL;
119 }
120 return 0;
121}73}
122 74
123/**75/**
@@ -231,9 +183,9 @@ static int amdgpu_verify_access(struct ttm_buffer_object *bo, struct file *filp) · 107 unmodified lines
231 * Assign the memory from new_mem to the memory of the buffer object bo.183 * Assign the memory from new_mem to the memory of the buffer object bo.
232 */184 */
233static void amdgpu_move_null(struct ttm_buffer_object *bo,185static void amdgpu_move_null(struct ttm_buffer_object *bo,
234 struct ttm_mem_reg *new_mem)186 struct ttm_resource *new_mem)
235{187{
236 struct ttm_mem_reg *old_mem = &bo->mem;188 struct ttm_resource *old_mem = &bo->mem;
237 189
238 BUG_ON(old_mem->mm_node != NULL);190 BUG_ON(old_mem->mm_node != NULL);
239 *old_mem = *new_mem;191 *old_mem = *new_mem;
@@ -250,7 +202,7 @@ static void amdgpu_move_null(struct ttm_buffer_object *bo, · 10 unmodified lines
250 */202 */
251static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,203static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo,
252 struct drm_mm_node *mm_node,204 struct drm_mm_node *mm_node,
253 struct ttm_mem_reg *mem)205 struct ttm_resource *mem)
254{206{
255 uint64_t addr = 0;207 uint64_t addr = 0;
256 208
@@ -270,7 +222,7 @@ static uint64_t amdgpu_mm_node_addr(struct ttm_buffer_object *bo, · 13 unmodified lines
270 * @offset: The offset that drm_mm_node is used for finding.222 * @offset: The offset that drm_mm_node is used for finding.
271 *223 *
272 */224 */
273static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem,225static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_resource *mem,
274 uint64_t *offset)226 uint64_t *offset)
275{227{
276 struct drm_mm_node *mm_node = mem->mm_node;228 struct drm_mm_node *mm_node = mem->mm_node;
@@ -298,7 +250,7 @@ static struct drm_mm_node *amdgpu_find_mm_node(struct ttm_mem_reg *mem, · 21 unmodified lines
298 * the physical address for local memory.250 * the physical address for local memory.
299 */251 */
300static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,252static int amdgpu_ttm_map_buffer(struct ttm_buffer_object *bo,
301 struct ttm_mem_reg *mem,253 struct ttm_resource *mem,
302 struct drm_mm_node *mm_node,254 struct drm_mm_node *mm_node,
303 unsigned num_pages, uint64_t offset,255 unsigned num_pages, uint64_t offset,
304 unsigned window, struct amdgpu_ring *ring,256 unsigned window, struct amdgpu_ring *ring,
@@ -522,8 +474,8 @@ error: · 217 unmodified lines
522 */474 */
523static int amdgpu_move_blit(struct ttm_buffer_object *bo,475static int amdgpu_move_blit(struct ttm_buffer_object *bo,
524 bool evict, bool no_wait_gpu,476 bool evict, bool no_wait_gpu,
525 struct ttm_mem_reg *new_mem,477 struct ttm_resource *new_mem,
526 struct ttm_mem_reg *old_mem)478 struct ttm_resource *old_mem)
527{479{
528 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);480 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
529 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);481 struct amdgpu_bo *abo = ttm_to_amdgpu_bo(bo);
@@ -582,10 +534,10 @@ error: · 52 unmodified lines
582 */534 */
583static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,535static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict,
584 struct ttm_operation_ctx *ctx,536 struct ttm_operation_ctx *ctx,
585 struct ttm_mem_reg *new_mem)537 struct ttm_resource *new_mem)
586{538{
587 struct ttm_mem_reg *old_mem = &bo->mem;539 struct ttm_resource *old_mem = &bo->mem;
588 struct ttm_mem_reg tmp_mem;540 struct ttm_resource tmp_mem;
589 struct ttm_place placements;541 struct ttm_place placements;
590 struct ttm_placement placement;542 struct ttm_placement placement;
591 int r;543 int r;
@@ -627,7 +579,7 @@ static int amdgpu_move_vram_ram(struct ttm_buffer_object *bo, bool evict, · 35 unmodified lines
627 /* move BO (in tmp_mem) to new_mem */579 /* move BO (in tmp_mem) to new_mem */
628 r = ttm_bo_move_ttm(bo, ctx, new_mem);580 r = ttm_bo_move_ttm(bo, ctx, new_mem);
629out_cleanup:581out_cleanup:
630 ttm_bo_mem_put(bo, &tmp_mem);582 ttm_resource_free(bo, &tmp_mem);
631 return r;583 return r;
632}584}
633 585
@@ -638,10 +590,10 @@ out_cleanup: · 4 unmodified lines
638 */590 */
639static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,591static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict,
640 struct ttm_operation_ctx *ctx,592 struct ttm_operation_ctx *ctx,
641 struct ttm_mem_reg *new_mem)593 struct ttm_resource *new_mem)
642{594{
643 struct ttm_mem_reg *old_mem = &bo->mem;595 struct ttm_resource *old_mem = &bo->mem;
644 struct ttm_mem_reg tmp_mem;596 struct ttm_resource tmp_mem;
645 struct ttm_placement placement;597 struct ttm_placement placement;
646 struct ttm_place placements;598 struct ttm_place placements;
647 int r;599 int r;
@@ -674,7 +626,7 @@ static int amdgpu_move_ram_vram(struct ttm_buffer_object *bo, bool evict, · 26 unmodified lines
674 goto out_cleanup;626 goto out_cleanup;
675 }627 }
676out_cleanup:628out_cleanup:
677 ttm_bo_mem_put(bo, &tmp_mem);629 ttm_resource_free(bo, &tmp_mem);
678 return r;630 return r;
679}631}
680 632
@@ -684,7 +636,7 @@ out_cleanup: · 3 unmodified lines
684 * Called by amdgpu_bo_move()636 * Called by amdgpu_bo_move()
685 */637 */
686static bool amdgpu_mem_visible(struct amdgpu_device *adev,638static bool amdgpu_mem_visible(struct amdgpu_device *adev,
687 struct ttm_mem_reg *mem)639 struct ttm_resource *mem)
688{640{
689 struct drm_mm_node *nodes = mem->mm_node;641 struct drm_mm_node *nodes = mem->mm_node;
690 642
@@ -694,7 +646,7 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev, · 3 unmodified lines
694 if (mem->mem_type != TTM_PL_VRAM)646 if (mem->mem_type != TTM_PL_VRAM)
695 return false;647 return false;
696 648
697 /* ttm_mem_reg_ioremap only supports contiguous memory */649 /* ttm_resource_ioremap only supports contiguous memory */
698 if (nodes->size != mem->num_pages)650 if (nodes->size != mem->num_pages)
699 return false;651 return false;
700 652
@@ -709,11 +661,11 @@ static bool amdgpu_mem_visible(struct amdgpu_device *adev, · 8 unmodified lines
709 */661 */
710static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,662static int amdgpu_bo_move(struct ttm_buffer_object *bo, bool evict,
711 struct ttm_operation_ctx *ctx,663 struct ttm_operation_ctx *ctx,
712 struct ttm_mem_reg *new_mem)664 struct ttm_resource *new_mem)
713{665{
714 struct amdgpu_device *adev;666 struct amdgpu_device *adev;
715 struct amdgpu_bo *abo;667 struct amdgpu_bo *abo;
716 struct ttm_mem_reg *old_mem = &bo->mem;668 struct ttm_resource *old_mem = &bo->mem;
717 int r;669 int r;
718 670
719 /* Can't move a pinned BO */671 /* Can't move a pinned BO */
@@ -795,19 +747,12 @@ memcpy: · 75 unmodified lines
795 *747 *
796 * Called by ttm_mem_io_reserve() ultimately via ttm_bo_vm_fault()748 * Called by ttm_mem_io_reserve() ultimately via ttm_bo_vm_fault()
797 */749 */
798static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)750static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_resource *mem)
799{751{
800 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
801 struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);752 struct amdgpu_device *adev = amdgpu_ttm_adev(bdev);
802 struct drm_mm_node *mm_node = mem->mm_node;753 struct drm_mm_node *mm_node = mem->mm_node;
754 size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;
803 755
804 mem->bus.addr = NULL;
805 mem->bus.offset = 0;
806 mem->bus.size = mem->num_pages << PAGE_SHIFT;
807 mem->bus.base = 0;
808 mem->bus.is_iomem = false;
809 if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
810 return -EINVAL;
811 switch (mem->mem_type) {756 switch (mem->mem_type) {
812 case TTM_PL_SYSTEM:757 case TTM_PL_SYSTEM:
813 /* system memory */758 /* system memory */
@@ -817,11 +762,11 @@ static int amdgpu_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_ · 3 unmodified lines
817 case TTM_PL_VRAM:762 case TTM_PL_VRAM:
818 mem->bus.offset = mem->start << PAGE_SHIFT;763 mem->bus.offset = mem->start << PAGE_SHIFT;
819 /* check if it's visible */764 /* check if it's visible */
820 if ((mem->bus.offset + mem->bus.size) > adev->gmc.visible_vram_size)765 if ((mem->bus.offset + bus_size) > adev->gmc.visible_vram_size)
821 return -EINVAL;766 return -EINVAL;
822 /* Only physically contiguous buffers apply. In a contiguous767 /* Only physically contiguous buffers apply. In a contiguous
823 * buffer, size of the first mm_node would match the number of768 * buffer, size of the first mm_node would match the number of
824 * pages in ttm_mem_reg.769 * pages in ttm_resource.
825 */770 */
826 if (adev->mman.aper_base_kaddr &&771 if (adev->mman.aper_base_kaddr &&
827 (mm_node->size == mem->num_pages))772 (mm_node->size == mem->num_pages))
@@ -1166,7 +1111,7 @@ gart_bind_fail: · 338 unmodified lines
1166 * This handles binding GTT memory to the device address space.1111 * This handles binding GTT memory to the device address space.
1167 */1112 */
1168static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,1113static int amdgpu_ttm_backend_bind(struct ttm_tt *ttm,
1169 struct ttm_mem_reg *bo_mem)1114 struct ttm_resource *bo_mem)
1170{1115{
1171 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);1116 struct amdgpu_device *adev = amdgpu_ttm_adev(ttm->bdev);
1172 struct amdgpu_ttm_tt *gtt = (void*)ttm;1117 struct amdgpu_ttm_tt *gtt = (void*)ttm;
@@ -1217,7 +1162,7 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) · 44 unmodified lines
1217 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);1162 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
1218 struct ttm_operation_ctx ctx = { false, false };1163 struct ttm_operation_ctx ctx = { false, false };
1219 struct amdgpu_ttm_tt *gtt = (void*)bo->ttm;1164 struct amdgpu_ttm_tt *gtt = (void*)bo->ttm;
1220 struct ttm_mem_reg tmp;1165 struct ttm_resource tmp;
1221 struct ttm_placement placement;1166 struct ttm_placement placement;
1222 struct ttm_place placements;1167 struct ttm_place placements;
1223 uint64_t addr, flags;1168 uint64_t addr, flags;
@@ -1254,11 +1199,11 @@ int amdgpu_ttm_alloc_gart(struct ttm_buffer_object *bo) · 30 unmodified lines
1254 gtt->offset = (u64)tmp.start << PAGE_SHIFT;1199 gtt->offset = (u64)tmp.start << PAGE_SHIFT;
1255 r = amdgpu_ttm_gart_bind(adev, bo, flags);1200 r = amdgpu_ttm_gart_bind(adev, bo, flags);
1256 if (unlikely(r)) {1201 if (unlikely(r)) {
1257 ttm_bo_mem_put(bo, &tmp);1202 ttm_resource_free(bo, &tmp);
1258 return r;1203 return r;
1259 }1204 }
1260 1205
1261 ttm_bo_mem_put(bo, &bo->mem);1206 ttm_resource_free(bo, &bo->mem);
1262 bo->mem = tmp;1207 bo->mem = tmp;
1263 }1208 }
1264 1209
@@ -1457,21 +1402,26 @@ static void amdgpu_ttm_tt_unpopulate(struct ttm_tt *ttm) · 192 unmodified lines
1457 * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current1402 * amdgpu_ttm_tt_set_userptr - Initialize userptr GTT ttm_tt for the current
1458 * task1403 * task
1459 *1404 *
1460 * @ttm: The ttm_tt object to bind this userptr object to1405 * @bo: The ttm_buffer_object to bind this userptr to
1461 * @addr: The address in the current tasks VM space to use1406 * @addr: The address in the current tasks VM space to use
1462 * @flags: Requirements of userptr object.1407 * @flags: Requirements of userptr object.
1463 *1408 *
1464 * Called by amdgpu_gem_userptr_ioctl() to bind userptr pages1409 * Called by amdgpu_gem_userptr_ioctl() to bind userptr pages
1465 * to current task1410 * to current task
1466 */1411 */
1467int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,1412int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
1468 uint32_t flags)1413 uint64_t addr, uint32_t flags)
1469{1414{
1470 struct amdgpu_ttm_tt *gtt = (void *)ttm;1415 struct amdgpu_ttm_tt *gtt;
1471 1416
1472 if (gtt == NULL)1417 if (!bo->ttm) {
1473 return -EINVAL;1418 /* TODO: We want a separate TTM object type for userptrs */
1419 bo->ttm = amdgpu_ttm_tt_create(bo, 0);
1420 if (bo->ttm == NULL)
1421 return -ENOMEM;
1422 }
1474 1423
1424 gtt = (void*)bo->ttm;
1475 gtt->userptr = addr;1425 gtt->userptr = addr;
1476 gtt->userflags = flags;1426 gtt->userflags = flags;
1477 1427
@@ -1557,7 +1507,7 @@ bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm) · 79 unmodified lines
1557 *1507 *
1558 * Figure out the flags to use for a VM PDE (Page Directory Entry).1508 * Figure out the flags to use for a VM PDE (Page Directory Entry).
1559 */1509 */
1560uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_mem_reg *mem)1510uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem)
1561{1511{
1562 uint64_t flags = 0;1512 uint64_t flags = 0;
1563 1513
@@ -1583,7 +1533,7 @@ uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_mem_reg *mem) · 19 unmodified lines
1583 * Figure out the flags to use for a VM PTE (Page Table Entry).1533 * Figure out the flags to use for a VM PTE (Page Table Entry).
1584 */1534 */
1585uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,1535uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
1586 struct ttm_mem_reg *mem)1536 struct ttm_resource *mem)
1587{1537{
1588 uint64_t flags = amdgpu_ttm_tt_pde_flags(ttm, mem);1538 uint64_t flags = amdgpu_ttm_tt_pde_flags(ttm, mem);
1589 1539
@@ -1741,7 +1691,6 @@ static struct ttm_bo_driver amdgpu_bo_driver = { · 151 unmodified lines
1741 .ttm_tt_create = &amdgpu_ttm_tt_create,1691 .ttm_tt_create = &amdgpu_ttm_tt_create,
1742 .ttm_tt_populate = &amdgpu_ttm_tt_populate,1692 .ttm_tt_populate = &amdgpu_ttm_tt_populate,
1743 .ttm_tt_unpopulate = &amdgpu_ttm_tt_unpopulate,1693 .ttm_tt_unpopulate = &amdgpu_ttm_tt_unpopulate,
1744 .init_mem_type = &amdgpu_init_mem_type,
1745 .eviction_valuable = amdgpu_ttm_bo_eviction_valuable,1694 .eviction_valuable = amdgpu_ttm_bo_eviction_valuable,
1746 .evict_flags = &amdgpu_evict_flags,1695 .evict_flags = &amdgpu_evict_flags,
1747 .move = &amdgpu_bo_move,1696 .move = &amdgpu_bo_move,
@@ -1936,8 +1885,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 188 unmodified lines
1936 adev->mman.bdev.no_retry = true;1885 adev->mman.bdev.no_retry = true;
1937 1886
1938 /* Initialize VRAM pool with all of VRAM divided into pages */1887 /* Initialize VRAM pool with all of VRAM divided into pages */
1939 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_VRAM,1888 r = amdgpu_vram_mgr_init(adev);
1940 adev->gmc.real_vram_size >> PAGE_SHIFT);
1941 if (r) {1889 if (r) {
1942 DRM_ERROR("Failed initializing VRAM heap.\n");1890 DRM_ERROR("Failed initializing VRAM heap.\n");
1943 return r;1891 return r;
@@ -2004,7 +1952,7 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 60 unmodified lines
2004 gtt_size = (uint64_t)amdgpu_gtt_size << 20;1952 gtt_size = (uint64_t)amdgpu_gtt_size << 20;
2005 1953
2006 /* Initialize GTT memory pool */1954 /* Initialize GTT memory pool */
2007 r = ttm_bo_init_mm(&adev->mman.bdev, TTM_PL_TT, gtt_size >> PAGE_SHIFT);1955 r = amdgpu_gtt_mgr_init(adev, gtt_size);
2008 if (r) {1956 if (r) {
2009 DRM_ERROR("Failed initializing GTT heap.\n");1957 DRM_ERROR("Failed initializing GTT heap.\n");
2010 return r;1958 return r;
@@ -2013,22 +1961,19 @@ int amdgpu_ttm_init(struct amdgpu_device *adev) · 2 unmodified lines
2013 (unsigned)(gtt_size / (1024 * 1024)));1961 (unsigned)(gtt_size / (1024 * 1024)));
2014 1962
2015 /* Initialize various on-chip memory pools */1963 /* Initialize various on-chip memory pools */
2016 r = ttm_bo_init_mm(&adev->mman.bdev, AMDGPU_PL_GDS,1964 r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_GDS, adev->gds.gds_size);
2017 adev->gds.gds_size);
2018 if (r) {1965 if (r) {
2019 DRM_ERROR("Failed initializing GDS heap.\n");1966 DRM_ERROR("Failed initializing GDS heap.\n");
2020 return r;1967 return r;
2021 }1968 }
2022 1969
2023 r = ttm_bo_init_mm(&adev->mman.bdev, AMDGPU_PL_GWS,1970 r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_GWS, adev->gds.gws_size);
2024 adev->gds.gws_size);
2025 if (r) {1971 if (r) {
2026 DRM_ERROR("Failed initializing gws heap.\n");1972 DRM_ERROR("Failed initializing gws heap.\n");
2027 return r;1973 return r;
2028 }1974 }
2029 1975
2030 r = ttm_bo_init_mm(&adev->mman.bdev, AMDGPU_PL_OA,1976 r = amdgpu_ttm_init_on_chip(adev, AMDGPU_PL_OA, adev->gds.oa_size);
2031 adev->gds.oa_size);
2032 if (r) {1977 if (r) {
2033 DRM_ERROR("Failed initializing oa heap.\n");1978 DRM_ERROR("Failed initializing oa heap.\n");
2034 return r;1979 return r;
@@ -2064,11 +2009,11 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) · 29 unmodified lines
2064 iounmap(adev->mman.aper_base_kaddr);2009 iounmap(adev->mman.aper_base_kaddr);
2065 adev->mman.aper_base_kaddr = NULL;2010 adev->mman.aper_base_kaddr = NULL;
2066 2011
2067 ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_VRAM);2012 amdgpu_vram_mgr_fini(adev);
2068 ttm_bo_clean_mm(&adev->mman.bdev, TTM_PL_TT);2013 amdgpu_gtt_mgr_fini(adev);
2069 ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_GDS);2014 ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GDS);
2070 ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_GWS);2015 ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_GWS);
2071 ttm_bo_clean_mm(&adev->mman.bdev, AMDGPU_PL_OA);2016 ttm_range_man_fini(&adev->mman.bdev, AMDGPU_PL_OA);
2072 ttm_bo_device_release(&adev->mman.bdev);2017 ttm_bo_device_release(&adev->mman.bdev);
2073 adev->mman.initialized = false;2018 adev->mman.initialized = false;
2074 DRM_INFO("amdgpu: ttm finalized\n");2019 DRM_INFO("amdgpu: ttm finalized\n");
@@ -2085,7 +2030,7 @@ void amdgpu_ttm_fini(struct amdgpu_device *adev) · 10 unmodified lines
2085 */2030 */
2086void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)2031void amdgpu_ttm_set_buffer_funcs_status(struct amdgpu_device *adev, bool enable)
2087{2032{
2088 struct ttm_mem_type_manager *man = &adev->mman.bdev.man[TTM_PL_VRAM];2033 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
2089 uint64_t size;2034 uint64_t size;
2090 int r;2035 int r;
2091 2036
@@ -2307,7 +2252,7 @@ static int amdgpu_mm_dump_table(struct seq_file *m, void *data) · 215 unmodified lines
2307 unsigned ttm_pl = (uintptr_t)node->info_ent->data;2252 unsigned ttm_pl = (uintptr_t)node->info_ent->data;
2308 struct drm_device *dev = node->minor->dev;2253 struct drm_device *dev = node->minor->dev;
2309 struct amdgpu_device *adev = dev->dev_private;2254 struct amdgpu_device *adev = dev->dev_private;
2310 struct ttm_mem_type_manager *man = &adev->mman.bdev.man[ttm_pl];2255 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, ttm_pl);
2311 struct drm_printer p = drm_seq_file_printer(m);2256 struct drm_printer p = drm_seq_file_printer(m);
2312 2257
2313 man->func->debug(man, &p);2258 man->func->debug(man, &p);
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.h+33−13
@@ -41,6 +41,21 @@ · 40 unmodified lines
41 41
42#define AMDGPU_POISON 0xd0bed0be42#define AMDGPU_POISON 0xd0bed0be
43 43
44struct amdgpu_vram_mgr {
45 struct ttm_resource_manager manager;
46 struct drm_mm mm;
47 spinlock_t lock;
48 atomic64_t usage;
49 atomic64_t vis_usage;
50};
51
52struct amdgpu_gtt_mgr {
53 struct ttm_resource_manager manager;
54 struct drm_mm mm;
55 spinlock_t lock;
56 atomic64_t available;
57};
58
44struct amdgpu_mman {59struct amdgpu_mman {
45 struct ttm_bo_device bdev;60 struct ttm_bo_device bdev;
46 bool mem_global_referenced;61 bool mem_global_referenced;
@@ -59,24 +74,29 @@ struct amdgpu_mman { · 12 unmodified lines
59 struct mutex gtt_window_lock;74 struct mutex gtt_window_lock;
60 /* Scheduler entity for buffer moves */75 /* Scheduler entity for buffer moves */
61 struct drm_sched_entity entity;76 struct drm_sched_entity entity;
77
78 struct amdgpu_vram_mgr vram_mgr;
79 struct amdgpu_gtt_mgr gtt_mgr;
62};80};
63 81
64struct amdgpu_copy_mem {82struct amdgpu_copy_mem {
65 struct ttm_buffer_object *bo;83 struct ttm_buffer_object *bo;
66 struct ttm_mem_reg *mem;84 struct ttm_resource *mem;
67 unsigned long offset;85 unsigned long offset;
68};86};
69 87
70extern const struct ttm_mem_type_manager_func amdgpu_gtt_mgr_func;88int amdgpu_gtt_mgr_init(struct amdgpu_device *adev, uint64_t gtt_size);
71extern const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func;89void amdgpu_gtt_mgr_fini(struct amdgpu_device *adev);
90int amdgpu_vram_mgr_init(struct amdgpu_device *adev);
91void amdgpu_vram_mgr_fini(struct amdgpu_device *adev);
72 92
73bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_mem_reg *mem);93bool amdgpu_gtt_mgr_has_gart_addr(struct ttm_resource *mem);
74uint64_t amdgpu_gtt_mgr_usage(struct ttm_mem_type_manager *man);94uint64_t amdgpu_gtt_mgr_usage(struct ttm_resource_manager *man);
75int amdgpu_gtt_mgr_recover(struct ttm_mem_type_manager *man);95int amdgpu_gtt_mgr_recover(struct ttm_resource_manager *man);
76 96
77u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo);97u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo);
78int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,98int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
79 struct ttm_mem_reg *mem,99 struct ttm_resource *mem,
80 struct device *dev,100 struct device *dev,
81 enum dma_data_direction dir,101 enum dma_data_direction dir,
82 struct sg_table **sgt);102 struct sg_table **sgt);
@@ -84,8 +104,8 @@ void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev, · 1 unmodified line
84 struct device *dev,104 struct device *dev,
85 enum dma_data_direction dir,105 enum dma_data_direction dir,
86 struct sg_table *sgt);106 struct sg_table *sgt);
87uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man);107uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man);
88uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man);108uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man);
89 109
90int amdgpu_ttm_init(struct amdgpu_device *adev);110int amdgpu_ttm_init(struct amdgpu_device *adev);
91void amdgpu_ttm_late_init(struct amdgpu_device *adev);111void amdgpu_ttm_late_init(struct amdgpu_device *adev);
@@ -130,8 +150,8 @@ static inline bool amdgpu_ttm_tt_get_user_pages_done(struct ttm_tt *ttm) · 38 unmodified lines
130#endif150#endif
131 151
132void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);152void amdgpu_ttm_tt_set_user_pages(struct ttm_tt *ttm, struct page **pages);
133int amdgpu_ttm_tt_set_userptr(struct ttm_tt *ttm, uint64_t addr,153int amdgpu_ttm_tt_set_userptr(struct ttm_buffer_object *bo,
134 uint32_t flags);154 uint64_t addr, uint32_t flags);
135bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);155bool amdgpu_ttm_tt_has_userptr(struct ttm_tt *ttm);
136struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);156struct mm_struct *amdgpu_ttm_tt_get_usermm(struct ttm_tt *ttm);
137bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,157bool amdgpu_ttm_tt_affect_userptr(struct ttm_tt *ttm, unsigned long start,
@@ -140,9 +160,9 @@ bool amdgpu_ttm_tt_userptr_invalidated(struct ttm_tt *ttm, · 2 unmodified lines
140 int *last_invalidated);160 int *last_invalidated);
141bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);161bool amdgpu_ttm_tt_is_userptr(struct ttm_tt *ttm);
142bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);162bool amdgpu_ttm_tt_is_readonly(struct ttm_tt *ttm);
143uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_mem_reg *mem);163uint64_t amdgpu_ttm_tt_pde_flags(struct ttm_tt *ttm, struct ttm_resource *mem);
144uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,164uint64_t amdgpu_ttm_tt_pte_flags(struct amdgpu_device *adev, struct ttm_tt *ttm,
145 struct ttm_mem_reg *mem);165 struct ttm_resource *mem);
146 166
147int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);167int amdgpu_ttm_debugfs_init(struct amdgpu_device *adev);
148 168
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c+1−1
@@ -1765,7 +1765,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, struct amdgpu_bo_va *bo_va, · 1764 unmodified lines
1765 struct amdgpu_vm *vm = bo_va->base.vm;1765 struct amdgpu_vm *vm = bo_va->base.vm;
1766 struct amdgpu_bo_va_mapping *mapping;1766 struct amdgpu_bo_va_mapping *mapping;
1767 dma_addr_t *pages_addr = NULL;1767 dma_addr_t *pages_addr = NULL;
1768 struct ttm_mem_reg *mem;1768 struct ttm_resource *mem;
1769 struct drm_mm_node *nodes;1769 struct drm_mm_node *nodes;
1770 struct dma_fence **last_update;1770 struct dma_fence **last_update;
1771 struct dma_resv *resv;1771 struct dma_resv *resv;
drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c+63−49
@@ -28,12 +28,15 @@ · 27 unmodified lines
28#include "amdgpu_atomfirmware.h"28#include "amdgpu_atomfirmware.h"
29#include "atom.h"29#include "atom.h"
30 30
31struct amdgpu_vram_mgr {31static inline struct amdgpu_vram_mgr *to_vram_mgr(struct ttm_resource_manager *man)
32 struct drm_mm mm;32{
33 spinlock_t lock;33 return container_of(man, struct amdgpu_vram_mgr, manager);
34 atomic64_t usage;34}
35 atomic64_t vis_usage;35
36};36static inline struct amdgpu_device *to_amdgpu_device(struct amdgpu_vram_mgr *mgr)
37{
38 return container_of(mgr, struct amdgpu_device, mman.vram_mgr);
39}
37 40
38/**41/**
39 * DOC: mem_info_vram_total42 * DOC: mem_info_vram_total
@@ -82,9 +85,9 @@ static ssize_t amdgpu_mem_info_vram_used_show(struct device *dev, · 42 unmodified lines
82{85{
83 struct drm_device *ddev = dev_get_drvdata(dev);86 struct drm_device *ddev = dev_get_drvdata(dev);
84 struct amdgpu_device *adev = ddev->dev_private;87 struct amdgpu_device *adev = ddev->dev_private;
85 88 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
86 return snprintf(buf, PAGE_SIZE, "%llu\n",89 return snprintf(buf, PAGE_SIZE, "%llu\n",
87 amdgpu_vram_mgr_usage(&adev->mman.bdev.man[TTM_PL_VRAM]));90 amdgpu_vram_mgr_usage(man));
88}91}
89 92
90/**93/**
@@ -100,9 +103,9 @@ static ssize_t amdgpu_mem_info_vis_vram_used_show(struct device *dev, · 9 unmodified lines
100{103{
101 struct drm_device *ddev = dev_get_drvdata(dev);104 struct drm_device *ddev = dev_get_drvdata(dev);
102 struct amdgpu_device *adev = ddev->dev_private;105 struct amdgpu_device *adev = ddev->dev_private;
103 106 struct ttm_resource_manager *man = ttm_manager_type(&adev->mman.bdev, TTM_PL_VRAM);
104 return snprintf(buf, PAGE_SIZE, "%llu\n",107 return snprintf(buf, PAGE_SIZE, "%llu\n",
105 amdgpu_vram_mgr_vis_usage(&adev->mman.bdev.man[TTM_PL_VRAM]));108 amdgpu_vram_mgr_vis_usage(man));
106}109}
107 110
108static ssize_t amdgpu_mem_info_vram_vendor(struct device *dev,111static ssize_t amdgpu_mem_info_vram_vendor(struct device *dev,
@@ -158,6 +161,8 @@ static const struct attribute *amdgpu_vram_mgr_attributes[] = { · 49 unmodified lines
158 NULL161 NULL
159};162};
160 163
164static const struct ttm_resource_manager_func amdgpu_vram_mgr_func;
165
161/**166/**
162 * amdgpu_vram_mgr_init - init VRAM manager and DRM MM167 * amdgpu_vram_mgr_init - init VRAM manager and DRM MM
163 *168 *
@@ -166,26 +171,29 @@ static const struct attribute *amdgpu_vram_mgr_attributes[] = { · 2 unmodified lines
166 *171 *
167 * Allocate and initialize the VRAM manager.172 * Allocate and initialize the VRAM manager.
168 */173 */
169static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man,174int amdgpu_vram_mgr_init(struct amdgpu_device *adev)
170 unsigned long p_size)
171{175{
172 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);176 struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
173 struct amdgpu_vram_mgr *mgr;177 struct ttm_resource_manager *man = &mgr->manager;
174 int ret;178 int ret;
175 179
176 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);180 man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
177 if (!mgr)181 man->default_caching = TTM_PL_FLAG_WC;
178 return -ENOMEM;
179 182
180 drm_mm_init(&mgr->mm, 0, p_size);183 ttm_resource_manager_init(man, adev->gmc.real_vram_size >> PAGE_SHIFT);
184
185 man->func = &amdgpu_vram_mgr_func;
186
187 drm_mm_init(&mgr->mm, 0, man->size);
181 spin_lock_init(&mgr->lock);188 spin_lock_init(&mgr->lock);
182 man->priv = mgr;
183 189
184 /* Add the two VRAM-related sysfs files */190 /* Add the two VRAM-related sysfs files */
185 ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);191 ret = sysfs_create_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);
186 if (ret)192 if (ret)
187 DRM_ERROR("Failed to register sysfs\n");193 DRM_ERROR("Failed to register sysfs\n");
188 194
195 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, &mgr->manager);
196 ttm_resource_manager_set_used(man, true);
189 return 0;197 return 0;
190}198}
191 199
@@ -197,18 +205,26 @@ static int amdgpu_vram_mgr_init(struct ttm_mem_type_manager *man, · 5 unmodified lines
197 * Destroy and free the VRAM manager, returns -EBUSY if ranges are still205 * Destroy and free the VRAM manager, returns -EBUSY if ranges are still
198 * allocated inside it.206 * allocated inside it.
199 */207 */
200static int amdgpu_vram_mgr_fini(struct ttm_mem_type_manager *man)208void amdgpu_vram_mgr_fini(struct amdgpu_device *adev)
201{209{
202 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);210 struct amdgpu_vram_mgr *mgr = &adev->mman.vram_mgr;
203 struct amdgpu_vram_mgr *mgr = man->priv;211 struct ttm_resource_manager *man = &mgr->manager;
212 int ret;
213
214 ttm_resource_manager_set_used(man, false);
215
216 ret = ttm_resource_manager_force_list_clean(&adev->mman.bdev, man);
217 if (ret)
218 return;
204 219
205 spin_lock(&mgr->lock);220 spin_lock(&mgr->lock);
206 drm_mm_takedown(&mgr->mm);221 drm_mm_takedown(&mgr->mm);
207 spin_unlock(&mgr->lock);222 spin_unlock(&mgr->lock);
208 kfree(mgr);223
209 man->priv = NULL;
210 sysfs_remove_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);224 sysfs_remove_files(&adev->dev->kobj, amdgpu_vram_mgr_attributes);
211 return 0;225
226 ttm_resource_manager_cleanup(man);
227 ttm_set_driver_manager(&adev->mman.bdev, TTM_PL_VRAM, NULL);
212}228}
213 229
214/**230/**
@@ -243,7 +259,7 @@ static u64 amdgpu_vram_mgr_vis_size(struct amdgpu_device *adev, · 28 unmodified lines
243u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo)259u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo)
244{260{
245 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);261 struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
246 struct ttm_mem_reg *mem = &bo->tbo.mem;262 struct ttm_resource *mem = &bo->tbo.mem;
247 struct drm_mm_node *nodes = mem->mm_node;263 struct drm_mm_node *nodes = mem->mm_node;
248 unsigned pages = mem->num_pages;264 unsigned pages = mem->num_pages;
249 u64 usage;265 u64 usage;
@@ -263,13 +279,13 @@ u64 amdgpu_vram_mgr_bo_visible_size(struct amdgpu_bo *bo) · 13 unmodified lines
263/**279/**
264 * amdgpu_vram_mgr_virt_start - update virtual start address280 * amdgpu_vram_mgr_virt_start - update virtual start address
265 *281 *
266 * @mem: ttm_mem_reg to update282 * @mem: ttm_resource to update
267 * @node: just allocated node283 * @node: just allocated node
268 *284 *
269 * Calculate a virtual BO start address to easily check if everything is CPU285 * Calculate a virtual BO start address to easily check if everything is CPU
270 * accessible.286 * accessible.
271 */287 */
272static void amdgpu_vram_mgr_virt_start(struct ttm_mem_reg *mem,288static void amdgpu_vram_mgr_virt_start(struct ttm_resource *mem,
273 struct drm_mm_node *node)289 struct drm_mm_node *node)
274{290{
275 unsigned long start;291 unsigned long start;
@@ -292,13 +308,13 @@ static void amdgpu_vram_mgr_virt_start(struct ttm_mem_reg *mem, · 16 unmodified lines
292 *308 *
293 * Allocate VRAM for the given BO.309 * Allocate VRAM for the given BO.
294 */310 */
295static int amdgpu_vram_mgr_new(struct ttm_mem_type_manager *man,311static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man,
296 struct ttm_buffer_object *tbo,312 struct ttm_buffer_object *tbo,
297 const struct ttm_place *place,313 const struct ttm_place *place,
298 struct ttm_mem_reg *mem)314 struct ttm_resource *mem)
299{315{
300 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);316 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
301 struct amdgpu_vram_mgr *mgr = man->priv;317 struct amdgpu_device *adev = to_amdgpu_device(mgr);
302 struct drm_mm *mm = &mgr->mm;318 struct drm_mm *mm = &mgr->mm;
303 struct drm_mm_node *nodes;319 struct drm_mm_node *nodes;
304 enum drm_mm_insert_mode mode;320 enum drm_mm_insert_mode mode;
@@ -410,11 +426,11 @@ error: · 105 unmodified lines
410 *426 *
411 * Free the allocated VRAM again.427 * Free the allocated VRAM again.
412 */428 */
413static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man,429static void amdgpu_vram_mgr_del(struct ttm_resource_manager *man,
414 struct ttm_mem_reg *mem)430 struct ttm_resource *mem)
415{431{
416 struct amdgpu_device *adev = amdgpu_ttm_adev(man->bdev);432 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
417 struct amdgpu_vram_mgr *mgr = man->priv;433 struct amdgpu_device *adev = to_amdgpu_device(mgr);
418 struct drm_mm_node *nodes = mem->mm_node;434 struct drm_mm_node *nodes = mem->mm_node;
419 uint64_t usage = 0, vis_usage = 0;435 uint64_t usage = 0, vis_usage = 0;
420 unsigned pages = mem->num_pages;436 unsigned pages = mem->num_pages;
@@ -451,7 +467,7 @@ static void amdgpu_vram_mgr_del(struct ttm_mem_type_manager *man, · 30 unmodified lines
451 * Allocate and fill a sg table from a VRAM allocation.467 * Allocate and fill a sg table from a VRAM allocation.
452 */468 */
453int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,469int amdgpu_vram_mgr_alloc_sgt(struct amdgpu_device *adev,
454 struct ttm_mem_reg *mem,470 struct ttm_resource *mem,
455 struct device *dev,471 struct device *dev,
456 enum dma_data_direction dir,472 enum dma_data_direction dir,
457 struct sg_table **sgt)473 struct sg_table **sgt)
@@ -544,9 +560,9 @@ void amdgpu_vram_mgr_free_sgt(struct amdgpu_device *adev, · 86 unmodified lines
544 *560 *
545 * Returns how many bytes are used in this domain.561 * Returns how many bytes are used in this domain.
546 */562 */
547uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man)563uint64_t amdgpu_vram_mgr_usage(struct ttm_resource_manager *man)
548{564{
549 struct amdgpu_vram_mgr *mgr = man->priv;565 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
550 566
551 return atomic64_read(&mgr->usage);567 return atomic64_read(&mgr->usage);
552}568}
@@ -558,9 +574,9 @@ uint64_t amdgpu_vram_mgr_usage(struct ttm_mem_type_manager *man) · 5 unmodified lines
558 *574 *
559 * Returns how many bytes are used in the visible part of VRAM575 * Returns how many bytes are used in the visible part of VRAM
560 */576 */
561uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man)577uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_resource_manager *man)
562{578{
563 struct amdgpu_vram_mgr *mgr = man->priv;579 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
564 580
565 return atomic64_read(&mgr->vis_usage);581 return atomic64_read(&mgr->vis_usage);
566}582}
@@ -573,10 +589,10 @@ uint64_t amdgpu_vram_mgr_vis_usage(struct ttm_mem_type_manager *man) · 6 unmodified lines
573 *589 *
574 * Dump the table content using printk.590 * Dump the table content using printk.
575 */591 */
576static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man,592static void amdgpu_vram_mgr_debug(struct ttm_resource_manager *man,
577 struct drm_printer *printer)593 struct drm_printer *printer)
578{594{
579 struct amdgpu_vram_mgr *mgr = man->priv;595 struct amdgpu_vram_mgr *mgr = to_vram_mgr(man);
580 596
581 spin_lock(&mgr->lock);597 spin_lock(&mgr->lock);
582 drm_mm_print(&mgr->mm, printer);598 drm_mm_print(&mgr->mm, printer);
@@ -587,10 +603,8 @@ static void amdgpu_vram_mgr_debug(struct ttm_mem_type_manager *man, · 4 unmodified lines
587 amdgpu_vram_mgr_vis_usage(man) >> 20);603 amdgpu_vram_mgr_vis_usage(man) >> 20);
588}604}
589 605
590const struct ttm_mem_type_manager_func amdgpu_vram_mgr_func = {606static const struct ttm_resource_manager_func amdgpu_vram_mgr_func = {
591 .init = amdgpu_vram_mgr_init,607 .alloc = amdgpu_vram_mgr_new,
592 .takedown = amdgpu_vram_mgr_fini,608 .free = amdgpu_vram_mgr_del,
593 .get_node = amdgpu_vram_mgr_new,609 .debug = amdgpu_vram_mgr_debug
594 .put_node = amdgpu_vram_mgr_del,
595 .debug = amdgpu_vram_mgr_debug
596};610};
drivers/gpu/drm/amd/amdgpu/atombios_dp.c+17−1
@@ -328,6 +328,22 @@ static void amdgpu_atombios_dp_probe_oui(struct amdgpu_connector *amdgpu_connect · 327 unmodified lines
328 buf[0], buf[1], buf[2]);328 buf[0], buf[1], buf[2]);
329}329}
330 330
331static void amdgpu_atombios_dp_ds_ports(struct amdgpu_connector *amdgpu_connector)
332{
333 struct amdgpu_connector_atom_dig *dig_connector = amdgpu_connector->con_priv;
334 int ret;
335
336 if (dig_connector->dpcd[DP_DPCD_REV] > 0x10) {
337 ret = drm_dp_dpcd_read(&amdgpu_connector->ddc_bus->aux,
338 DP_DOWNSTREAM_PORT_0,
339 dig_connector->downstream_ports,
340 DP_MAX_DOWNSTREAM_PORTS);
341 if (ret)
342 memset(dig_connector->downstream_ports, 0,
343 DP_MAX_DOWNSTREAM_PORTS);
344 }
345}
346
331int amdgpu_atombios_dp_get_dpcd(struct amdgpu_connector *amdgpu_connector)347int amdgpu_atombios_dp_get_dpcd(struct amdgpu_connector *amdgpu_connector)
332{348{
333 struct amdgpu_connector_atom_dig *dig_connector = amdgpu_connector->con_priv;349 struct amdgpu_connector_atom_dig *dig_connector = amdgpu_connector->con_priv;
@@ -343,7 +359,7 @@ int amdgpu_atombios_dp_get_dpcd(struct amdgpu_connector *amdgpu_connector) · 9 unmodified lines
343 dig_connector->dpcd);359 dig_connector->dpcd);
344 360
345 amdgpu_atombios_dp_probe_oui(amdgpu_connector);361 amdgpu_atombios_dp_probe_oui(amdgpu_connector);
346 362 amdgpu_atombios_dp_ds_ports(amdgpu_connector);
347 return 0;363 return 0;
348 }364 }
349 365
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c+40−1
@@ -127,6 +127,42 @@ MODULE_FIRMWARE(FIRMWARE_NAVI12_DMCU); · 126 unmodified lines
127static int amdgpu_dm_init(struct amdgpu_device *adev);127static int amdgpu_dm_init(struct amdgpu_device *adev);
128static void amdgpu_dm_fini(struct amdgpu_device *adev);128static void amdgpu_dm_fini(struct amdgpu_device *adev);
129 129
130static enum drm_mode_subconnector get_subconnector_type(struct dc_link *link)
131{
132 switch (link->dpcd_caps.dongle_type) {
133 case DISPLAY_DONGLE_NONE:
134 return DRM_MODE_SUBCONNECTOR_Native;
135 case DISPLAY_DONGLE_DP_VGA_CONVERTER:
136 return DRM_MODE_SUBCONNECTOR_VGA;
137 case DISPLAY_DONGLE_DP_DVI_CONVERTER:
138 case DISPLAY_DONGLE_DP_DVI_DONGLE:
139 return DRM_MODE_SUBCONNECTOR_DVID;
140 case DISPLAY_DONGLE_DP_HDMI_CONVERTER:
141 case DISPLAY_DONGLE_DP_HDMI_DONGLE:
142 return DRM_MODE_SUBCONNECTOR_HDMIA;
143 case DISPLAY_DONGLE_DP_HDMI_MISMATCHED_DONGLE:
144 default:
145 return DRM_MODE_SUBCONNECTOR_Unknown;
146 }
147}
148
149static void update_subconnector_property(struct amdgpu_dm_connector *aconnector)
150{
151 struct dc_link *link = aconnector->dc_link;
152 struct drm_connector *connector = &aconnector->base;
153 enum drm_mode_subconnector subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
154
155 if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
156 return;
157
158 if (aconnector->dc_sink)
159 subconnector = get_subconnector_type(link);
160
161 drm_object_property_set_value(&connector->base,
162 connector->dev->mode_config.dp_subconnector_property,
163 subconnector);
164}
165
130/*166/*
131 * initializes drm_device display related structures, based on the information167 * initializes drm_device display related structures, based on the information
132 * provided by DAL. The drm strcutures are: drm_crtc, drm_connector,168 * provided by DAL. The drm strcutures are: drm_crtc, drm_connector,
@@ -2095,7 +2131,6 @@ void amdgpu_dm_update_connector_after_detect( · 1962 unmodified lines
2095 if (aconnector->mst_mgr.mst_state == true)2131 if (aconnector->mst_mgr.mst_state == true)
2096 return;2132 return;
2097 2133
2098
2099 sink = aconnector->dc_link->local_sink;2134 sink = aconnector->dc_link->local_sink;
2100 if (sink)2135 if (sink)
2101 dc_sink_retain(sink);2136 dc_sink_retain(sink);
@@ -2222,6 +2257,8 @@ void amdgpu_dm_update_connector_after_detect( · 120 unmodified lines
2222 2257
2223 mutex_unlock(&dev->mode_config.mutex);2258 mutex_unlock(&dev->mode_config.mutex);
2224 2259
2260 update_subconnector_property(aconnector);
2261
2225 if (sink)2262 if (sink)
2226 dc_sink_release(sink);2263 dc_sink_release(sink);
2227}2264}
@@ -4757,6 +4794,8 @@ amdgpu_dm_connector_detect(struct drm_connector *connector, bool force) · 2529 unmodified lines
4757 else4794 else
4758 connected = (aconnector->base.force == DRM_FORCE_ON);4795 connected = (aconnector->base.force == DRM_FORCE_ON);
4759 4796
4797 update_subconnector_property(aconnector);
4798
4760 return (connected ? connector_status_connected :4799 return (connected ? connector_status_connected :
4761 connector_status_disconnected);4800 connector_status_disconnected);
4762}4801}
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c+3−0
@@ -26,6 +26,7 @@ · 25 unmodified lines
26#include <linux/version.h>26#include <linux/version.h>
27#include <drm/drm_atomic_helper.h>27#include <drm/drm_atomic_helper.h>
28#include <drm/drm_dp_mst_helper.h>28#include <drm/drm_dp_mst_helper.h>
29#include <drm/drm_dp_helper.h>
29#include "dm_services.h"30#include "dm_services.h"
30#include "amdgpu.h"31#include "amdgpu.h"
31#include "amdgpu_dm.h"32#include "amdgpu_dm.h"
@@ -431,6 +432,8 @@ void amdgpu_dm_initialize_dp_connector(struct amdgpu_display_manager *dm, · 399 unmodified lines
431 16,432 16,
432 4,433 4,
433 aconnector->connector_id);434 aconnector->connector_id);
435
436 drm_connector_attach_dp_subconnector_property(&aconnector->base);
434}437}
435 438
436int dm_mst_get_pbn_divider(struct dc_link *link)439int dm_mst_get_pbn_divider(struct dc_link *link)
drivers/gpu/drm/arm/malidp_planes.c+1−1
@@ -346,7 +346,7 @@ static bool malidp_check_pages_threshold(struct malidp_plane_state *ms, · 345 unmodified lines
346 if (cma_obj->sgt)346 if (cma_obj->sgt)
347 sgt = cma_obj->sgt;347 sgt = cma_obj->sgt;
348 else348 else
349 sgt = obj->dev->driver->gem_prime_get_sg_table(obj);349 sgt = obj->funcs->get_sg_table(obj);
350 350
351 if (!sgt)351 if (!sgt)
352 return false;352 return false;
drivers/gpu/drm/ast/ast_cursor.c+6−5
@@ -47,7 +47,7 @@ static void ast_cursor_fini(struct ast_private *ast) · 46 unmodified lines
47 47
48static void ast_cursor_release(struct drm_device *dev, void *ptr)48static void ast_cursor_release(struct drm_device *dev, void *ptr)
49{49{
50 struct ast_private *ast = dev->dev_private;50 struct ast_private *ast = to_ast_private(dev);
51 51
52 ast_cursor_fini(ast);52 ast_cursor_fini(ast);
53}53}
@@ -57,7 +57,7 @@ static void ast_cursor_release(struct drm_device *dev, void *ptr) · 3 unmodified lines
57 */57 */
58int ast_cursor_init(struct ast_private *ast)58int ast_cursor_init(struct ast_private *ast)
59{59{
60 struct drm_device *dev = ast->dev;60 struct drm_device *dev = &ast->base;
61 size_t size, i;61 size_t size, i;
62 struct drm_gem_vram_object *gbo;62 struct drm_gem_vram_object *gbo;
63 void __iomem *vaddr;63 void __iomem *vaddr;
@@ -168,7 +168,7 @@ static void update_cursor_image(u8 __iomem *dst, const u8 *src, int width, int h · 104 unmodified lines
168 168
169int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)169int ast_cursor_blit(struct ast_private *ast, struct drm_framebuffer *fb)
170{170{
171 struct drm_device *dev = ast->dev;171 struct drm_device *dev = &ast->base;
172 struct drm_gem_vram_object *gbo;172 struct drm_gem_vram_object *gbo;
173 int ret;173 int ret;
174 void *src;174 void *src;
@@ -217,7 +217,7 @@ static void ast_cursor_set_base(struct ast_private *ast, u64 address) · 42 unmodified lines
217 217
218void ast_cursor_page_flip(struct ast_private *ast)218void ast_cursor_page_flip(struct ast_private *ast)
219{219{
220 struct drm_device *dev = ast->dev;220 struct drm_device *dev = &ast->base;
221 struct drm_gem_vram_object *gbo;221 struct drm_gem_vram_object *gbo;
222 s64 off;222 s64 off;
223 223
@@ -253,7 +253,8 @@ void ast_cursor_show(struct ast_private *ast, int x, int y, · 29 unmodified lines
253 unsigned int offset_x, unsigned int offset_y)253 unsigned int offset_x, unsigned int offset_y)
254{254{
255 u8 x_offset, y_offset;255 u8 x_offset, y_offset;
256 u8 __iomem *dst, __iomem *sig;256 u8 __iomem *dst;
257 u8 __iomem *sig;
257 u8 jreg;258 u8 jreg;
258 259
259 dst = ast->cursor.vaddr[ast->cursor.next_index];260 dst = ast->cursor.vaddr[ast->cursor.next_index];
drivers/gpu/drm/ast/ast_dp501.c+14−9
@@ -8,11 +8,24 @@ · 7 unmodified lines
8 8
9MODULE_FIRMWARE("ast_dp501_fw.bin");9MODULE_FIRMWARE("ast_dp501_fw.bin");
10 10
11static void ast_release_firmware(void *data)
12{
13 struct ast_private *ast = data;
14
15 release_firmware(ast->dp501_fw);
16 ast->dp501_fw = NULL;
17}
18
11static int ast_load_dp501_microcode(struct drm_device *dev)19static int ast_load_dp501_microcode(struct drm_device *dev)
12{20{
13 struct ast_private *ast = to_ast_private(dev);21 struct ast_private *ast = to_ast_private(dev);
22 int ret;
23
24 ret = request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);
25 if (ret)
26 return ret;
14 27
15 return request_firmware(&ast->dp501_fw, "ast_dp501_fw.bin", dev->dev);28 return devm_add_action_or_reset(dev->dev, ast_release_firmware, ast);
16}29}
17 30
18static void send_ack(struct ast_private *ast)31static void send_ack(struct ast_private *ast)
@@ -435,11 +448,3 @@ void ast_init_3rdtx(struct drm_device *dev) · 416 unmodified lines
435 }448 }
436 }449 }
437}450}
438
439void ast_release_firmware(struct drm_device *dev)
440{
441 struct ast_private *ast = to_ast_private(dev);
442
443 release_firmware(ast->dp501_fw);
444 ast->dp501_fw = NULL;
445}
drivers/gpu/drm/ast/ast_drv.c+36−46
@@ -43,9 +43,33 @@ int ast_modeset = -1; · 42 unmodified lines
43MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");43MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
44module_param_named(modeset, ast_modeset, int, 0400);44module_param_named(modeset, ast_modeset, int, 0400);
45 45
46#define PCI_VENDOR_ASPEED 0x1a0346/*
47 * DRM driver
48 */
49
50DEFINE_DRM_GEM_FOPS(ast_fops);
51
52static struct drm_driver ast_driver = {
53 .driver_features = DRIVER_ATOMIC |
54 DRIVER_GEM |
55 DRIVER_MODESET,
56
57 .fops = &ast_fops,
58 .name = DRIVER_NAME,
59 .desc = DRIVER_DESC,
60 .date = DRIVER_DATE,
61 .major = DRIVER_MAJOR,
62 .minor = DRIVER_MINOR,
63 .patchlevel = DRIVER_PATCHLEVEL,
64
65 DRM_GEM_VRAM_DRIVER
66};
67
68/*
69 * PCI driver
70 */
47 71
48static struct drm_driver driver;72#define PCI_VENDOR_ASPEED 0x1a03
49 73
50#define AST_VGA_DEVICE(id, info) { \74#define AST_VGA_DEVICE(id, info) { \
51 .class = PCI_BASE_CLASS_DISPLAY << 16, \75 .class = PCI_BASE_CLASS_DISPLAY << 16, \
@@ -56,13 +80,13 @@ static struct drm_driver driver; · 4 unmodified lines
56 .subdevice = PCI_ANY_ID, \80 .subdevice = PCI_ANY_ID, \
57 .driver_data = (unsigned long) info }81 .driver_data = (unsigned long) info }
58 82
59static const struct pci_device_id pciidlist[] = {83static const struct pci_device_id ast_pciidlist[] = {
60 AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),84 AST_VGA_DEVICE(PCI_CHIP_AST2000, NULL),
61 AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),85 AST_VGA_DEVICE(PCI_CHIP_AST2100, NULL),
62 {0, 0, 0},86 {0, 0, 0},
63};87};
64 88
65MODULE_DEVICE_TABLE(pci, pciidlist);89MODULE_DEVICE_TABLE(pci, ast_pciidlist);
66 90
67static void ast_kick_out_firmware_fb(struct pci_dev *pdev)91static void ast_kick_out_firmware_fb(struct pci_dev *pdev)
68{92{
@@ -85,6 +109,7 @@ static void ast_kick_out_firmware_fb(struct pci_dev *pdev) · 16 unmodified lines
85 109
86static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)110static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
87{111{
112 struct ast_private *ast;
88 struct drm_device *dev;113 struct drm_device *dev;
89 int ret;114 int ret;
90 115
@@ -94,41 +119,25 @@ static int ast_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 3 unmodified lines
94 if (ret)119 if (ret)
95 return ret;120 return ret;
96 121
97 dev = drm_dev_alloc(&driver, &pdev->dev);122 ast = ast_device_create(&ast_driver, pdev, ent->driver_data);
98 if (IS_ERR(dev))123 if (IS_ERR(ast))
99 return PTR_ERR(dev);124 return PTR_ERR(ast);
100 125 dev = &ast->base;
101 dev->pdev = pdev;
102 pci_set_drvdata(pdev, dev);
103
104 ret = ast_driver_load(dev, ent->driver_data);
105 if (ret)
106 goto err_drm_dev_put;
107 126
108 ret = drm_dev_register(dev, ent->driver_data);127 ret = drm_dev_register(dev, ent->driver_data);
109 if (ret)128 if (ret)
110 goto err_ast_driver_unload;129 return ret;
111 130
112 drm_fbdev_generic_setup(dev, 32);131 drm_fbdev_generic_setup(dev, 32);
113 132
114 return 0;133 return 0;
115
116err_ast_driver_unload:
117 ast_driver_unload(dev);
118err_drm_dev_put:
119 drm_dev_put(dev);
120 return ret;
121
122}134}
123 135
124static void136static void ast_pci_remove(struct pci_dev *pdev)
125ast_pci_remove(struct pci_dev *pdev)
126{137{
127 struct drm_device *dev = pci_get_drvdata(pdev);138 struct drm_device *dev = pci_get_drvdata(pdev);
128 139
129 drm_dev_unregister(dev);140 drm_dev_unregister(dev);
130 ast_driver_unload(dev);
131 drm_dev_put(dev);
132}141}
133 142
134static int ast_drm_freeze(struct drm_device *dev)143static int ast_drm_freeze(struct drm_device *dev)
@@ -217,30 +226,12 @@ static const struct dev_pm_ops ast_pm_ops = { · 82 unmodified lines
217 226
218static struct pci_driver ast_pci_driver = {227static struct pci_driver ast_pci_driver = {
219 .name = DRIVER_NAME,228 .name = DRIVER_NAME,
220 .id_table = pciidlist,229 .id_table = ast_pciidlist,
221 .probe = ast_pci_probe,230 .probe = ast_pci_probe,
222 .remove = ast_pci_remove,231 .remove = ast_pci_remove,
223 .driver.pm = &ast_pm_ops,232 .driver.pm = &ast_pm_ops,
224};233};
225 234
226DEFINE_DRM_GEM_FOPS(ast_fops);
227
228static struct drm_driver driver = {
229 .driver_features = DRIVER_ATOMIC |
230 DRIVER_GEM |
231 DRIVER_MODESET,
232
233 .fops = &ast_fops,
234 .name = DRIVER_NAME,
235 .desc = DRIVER_DESC,
236 .date = DRIVER_DATE,
237 .major = DRIVER_MAJOR,
238 .minor = DRIVER_MINOR,
239 .patchlevel = DRIVER_PATCHLEVEL,
240
241 DRM_GEM_VRAM_DRIVER
242};
243
244static int __init ast_init(void)235static int __init ast_init(void)
245{236{
246 if (vgacon_text_force() && ast_modeset == -1)237 if (vgacon_text_force() && ast_modeset == -1)
@@ -261,4 +252,3 @@ module_exit(ast_exit); · 14 unmodified lines
261MODULE_AUTHOR(DRIVER_AUTHOR);252MODULE_AUTHOR(DRIVER_AUTHOR);
262MODULE_DESCRIPTION(DRIVER_DESC);253MODULE_DESCRIPTION(DRIVER_DESC);
263MODULE_LICENSE("GPL and additional rights");254MODULE_LICENSE("GPL and additional rights");
264
drivers/gpu/drm/ast/ast_drv.h+24−19
@@ -98,9 +98,25 @@ enum ast_tx_chip { · 97 unmodified lines
98#define AST_HWC_SIGNATURE_HOTSPOTX 0x1498#define AST_HWC_SIGNATURE_HOTSPOTX 0x14
99#define AST_HWC_SIGNATURE_HOTSPOTY 0x1899#define AST_HWC_SIGNATURE_HOTSPOTY 0x18
100 100
101struct ast_i2c_chan {
102 struct i2c_adapter adapter;
103 struct drm_device *dev;
104 struct i2c_algo_bit_data bit;
105};
106
107struct ast_connector {
108 struct drm_connector base;
109 struct ast_i2c_chan *i2c;
110};
111
112static inline struct ast_connector *
113to_ast_connector(struct drm_connector *connector)
114{
115 return container_of(connector, struct ast_connector, base);
116}
101 117
102struct ast_private {118struct ast_private {
103 struct drm_device *dev;119 struct drm_device base;
104 120
105 void __iomem *regs;121 void __iomem *regs;
106 void __iomem *ioregs;122 void __iomem *ioregs;
@@ -119,9 +135,11 @@ struct ast_private { · 12 unmodified lines
119 unsigned int next_index;135 unsigned int next_index;
120 } cursor;136 } cursor;
121 137
122 struct drm_encoder encoder;
123 struct drm_plane primary_plane;138 struct drm_plane primary_plane;
124 struct drm_plane cursor_plane;139 struct drm_plane cursor_plane;
140 struct drm_crtc crtc;
141 struct drm_encoder encoder;
142 struct ast_connector connector;
125 143
126 bool support_wide_screen;144 bool support_wide_screen;
127 enum {145 enum {
@@ -138,11 +156,12 @@ struct ast_private { · 10 unmodified lines
138 156
139static inline struct ast_private *to_ast_private(struct drm_device *dev)157static inline struct ast_private *to_ast_private(struct drm_device *dev)
140{158{
141 return dev->dev_private;159 return container_of(dev, struct ast_private, base);
142}160}
143 161
144int ast_driver_load(struct drm_device *dev, unsigned long flags);162struct ast_private *ast_device_create(struct drm_driver *drv,
145void ast_driver_unload(struct drm_device *dev);163 struct pci_dev *pdev,
164 unsigned long flags);
146 165
147#define AST_IO_AR_PORT_WRITE (0x40)166#define AST_IO_AR_PORT_WRITE (0x40)
148#define AST_IO_MISC_PORT_WRITE (0x42)167#define AST_IO_MISC_PORT_WRITE (0x42)
@@ -226,19 +245,6 @@ static inline void ast_open_key(struct ast_private *ast) · 77 unmodified lines
226 245
227#define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M246#define AST_VIDMEM_DEFAULT_SIZE AST_VIDMEM_SIZE_8M
228 247
229struct ast_i2c_chan {
230 struct i2c_adapter adapter;
231 struct drm_device *dev;
232 struct i2c_algo_bit_data bit;
233};
234
235struct ast_connector {
236 struct drm_connector base;
237 struct ast_i2c_chan *i2c;
238};
239
240#define to_ast_connector(x) container_of(x, struct ast_connector, base)
241
242struct ast_vbios_stdtable {248struct ast_vbios_stdtable {
243 u8 misc;249 u8 misc;
244 u8 seq[4];250 u8 seq[4];
@@ -305,7 +311,6 @@ bool ast_backup_fw(struct drm_device *dev, u8 *addr, u32 size); · 60 unmodified lines
305bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);311bool ast_dp501_read_edid(struct drm_device *dev, u8 *ediddata);
306u8 ast_get_dp501_max_clk(struct drm_device *dev);312u8 ast_get_dp501_max_clk(struct drm_device *dev);
307void ast_init_3rdtx(struct drm_device *dev);313void ast_init_3rdtx(struct drm_device *dev);
308void ast_release_firmware(struct drm_device *dev);
309 314
310/* ast_cursor.c */315/* ast_cursor.c */
311int ast_cursor_init(struct ast_private *ast);316int ast_cursor_init(struct ast_private *ast);
drivers/gpu/drm/ast/ast_main.c+38−36
@@ -30,8 +30,10 @@ · 29 unmodified lines
30 30
31#include <drm/drm_atomic_helper.h>31#include <drm/drm_atomic_helper.h>
32#include <drm/drm_crtc_helper.h>32#include <drm/drm_crtc_helper.h>
33#include <drm/drm_drv.h>
33#include <drm/drm_gem.h>34#include <drm/drm_gem.h>
34#include <drm/drm_gem_vram_helper.h>35#include <drm/drm_gem_vram_helper.h>
36#include <drm/drm_managed.h>
35 37
36#include "ast_drv.h"38#include "ast_drv.h"
37 39
@@ -230,11 +232,11 @@ static int ast_detect_chip(struct drm_device *dev, bool *need_post) · 192 unmodified lines
230 ast->tx_chip_type = AST_TX_SIL164;232 ast->tx_chip_type = AST_TX_SIL164;
231 break;233 break;
232 case 0x08:234 case 0x08:
233 ast->dp501_fw_addr = kzalloc(32*1024, GFP_KERNEL);235 ast->dp501_fw_addr = drmm_kzalloc(dev, 32*1024, GFP_KERNEL);
234 if (ast->dp501_fw_addr) {236 if (ast->dp501_fw_addr) {
235 /* backup firmware */237 /* backup firmware */
236 if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {238 if (ast_backup_fw(dev, ast->dp501_fw_addr, 32*1024)) {
237 kfree(ast->dp501_fw_addr);239 drmm_kfree(dev, ast->dp501_fw_addr);
238 ast->dp501_fw_addr = NULL;240 ast->dp501_fw_addr = NULL;
239 }241 }
240 }242 }
@@ -378,24 +380,38 @@ static int ast_get_dram_info(struct drm_device *dev) · 137 unmodified lines
378 return 0;380 return 0;
379}381}
380 382
381int ast_driver_load(struct drm_device *dev, unsigned long flags)383/*
384 * Run this function as part of the HW device cleanup; not
385 * when the DRM device gets released.
386 */
387static void ast_device_release(void *data)
382{388{
389 struct ast_private *ast = data;
390
391 /* enable standard VGA decode */
392 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
393}
394
395struct ast_private *ast_device_create(struct drm_driver *drv,
396 struct pci_dev *pdev,
397 unsigned long flags)
398{
399 struct drm_device *dev;
383 struct ast_private *ast;400 struct ast_private *ast;
384 bool need_post;401 bool need_post;
385 int ret = 0;402 int ret = 0;
386 403
387 ast = kzalloc(sizeof(struct ast_private), GFP_KERNEL);404 ast = devm_drm_dev_alloc(&pdev->dev, drv, struct ast_private, base);
388 if (!ast)405 if (IS_ERR(ast))
389 return -ENOMEM;406 return ast;
407 dev = &ast->base;
390 408
391 dev->dev_private = ast;409 dev->pdev = pdev;
392 ast->dev = dev;410 pci_set_drvdata(pdev, dev);
393 411
394 ast->regs = pci_iomap(dev->pdev, 1, 0);412 ast->regs = pci_iomap(dev->pdev, 1, 0);
395 if (!ast->regs) {413 if (!ast->regs)
396 ret = -EIO;414 return ERR_PTR(-EIO);
397 goto out_free;
398 }
399 415
400 /*416 /*
401 * If we don't have IO space at all, use MMIO now and417 * If we don't have IO space at all, use MMIO now and
@@ -410,17 +426,16 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) · 8 unmodified lines
410 /* "map" IO regs if the above hasn't done so already */426 /* "map" IO regs if the above hasn't done so already */
411 if (!ast->ioregs) {427 if (!ast->ioregs) {
412 ast->ioregs = pci_iomap(dev->pdev, 2, 0);428 ast->ioregs = pci_iomap(dev->pdev, 2, 0);
413 if (!ast->ioregs) {429 if (!ast->ioregs)
414 ret = -EIO;430 return ERR_PTR(-EIO);
415 goto out_free;
416 }
417 }431 }
418 432
419 ast_detect_chip(dev, &need_post);433 ast_detect_chip(dev, &need_post);
420 434
421 ret = ast_get_dram_info(dev);435 ret = ast_get_dram_info(dev);
422 if (ret)436 if (ret)
423 goto out_free;437 return ERR_PTR(ret);
438
424 drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d\n",439 drm_info(dev, "dram MCLK=%u Mhz type=%d bus_width=%d\n",
425 ast->mclk, ast->dram_type, ast->dram_bus_width);440 ast->mclk, ast->dram_type, ast->dram_bus_width);
426 441
@@ -429,28 +444,15 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags) · 2 unmodified lines
429 444
430 ret = ast_mm_init(ast);445 ret = ast_mm_init(ast);
431 if (ret)446 if (ret)
432 goto out_free;447 return ERR_PTR(ret);
433 448
434 ret = ast_mode_config_init(ast);449 ret = ast_mode_config_init(ast);
435 if (ret)450 if (ret)
436 goto out_free;451 return ERR_PTR(ret);
437 452
438 return 0;453 ret = devm_add_action_or_reset(dev->dev, ast_device_release, ast);
439out_free:454 if (ret)
440 kfree(ast);455 return ERR_PTR(ret);
441 dev->dev_private = NULL;
442 return ret;
443}
444
445void ast_driver_unload(struct drm_device *dev)
446{
447 struct ast_private *ast = to_ast_private(dev);
448
449 /* enable standard VGA decode */
450 ast_set_index_reg(ast, AST_IO_CRTC_PORT, 0xa1, 0x04);
451
452 ast_release_firmware(dev);
453 kfree(ast->dp501_fw_addr);
454 456
455 kfree(ast);457 return ast;
456}458}
drivers/gpu/drm/ast/ast_mm.c+1−1
@@ -85,9 +85,9 @@ static void ast_mm_release(struct drm_device *dev, void *ptr) · 84 unmodified lines
85 85
86int ast_mm_init(struct ast_private *ast)86int ast_mm_init(struct ast_private *ast)
87{87{
88 struct drm_device *dev = &ast->base;
88 u32 vram_size;89 u32 vram_size;
89 int ret;90 int ret;
90 struct drm_device *dev = ast->dev;
91 91
92 vram_size = ast_get_vram_size(ast);92 vram_size = ast_get_vram_size(ast);
93 93
drivers/gpu/drm/ast/ast_mode.c+10−30
@@ -663,7 +663,7 @@ ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, · 662 unmodified lines
663{663{
664 struct drm_plane_state *state = plane->state;664 struct drm_plane_state *state = plane->state;
665 struct drm_framebuffer *fb = state->fb;665 struct drm_framebuffer *fb = state->fb;
666 struct ast_private *ast = plane->dev->dev_private;666 struct ast_private *ast = to_ast_private(plane->dev);
667 unsigned int offset_x, offset_y;667 unsigned int offset_x, offset_y;
668 668
669 offset_x = AST_MAX_HWC_WIDTH - fb->width;669 offset_x = AST_MAX_HWC_WIDTH - fb->width;
@@ -831,12 +831,6 @@ static void ast_crtc_reset(struct drm_crtc *crtc) · 161 unmodified lines
831 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);831 __drm_atomic_helper_crtc_reset(crtc, &ast_state->base);
832}832}
833 833
834static void ast_crtc_destroy(struct drm_crtc *crtc)
835{
836 drm_crtc_cleanup(crtc);
837 kfree(crtc);
838}
839
840static struct drm_crtc_state *834static struct drm_crtc_state *
841ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)835ast_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
842{836{
@@ -872,7 +866,7 @@ static void ast_crtc_atomic_destroy_state(struct drm_crtc *crtc, · 29 unmodified lines
872static const struct drm_crtc_funcs ast_crtc_funcs = {866static const struct drm_crtc_funcs ast_crtc_funcs = {
873 .reset = ast_crtc_reset,867 .reset = ast_crtc_reset,
874 .gamma_set = drm_atomic_helper_legacy_gamma_set,868 .gamma_set = drm_atomic_helper_legacy_gamma_set,
875 .destroy = ast_crtc_destroy,869 .destroy = drm_crtc_cleanup,
876 .set_config = drm_atomic_helper_set_config,870 .set_config = drm_atomic_helper_set_config,
877 .page_flip = drm_atomic_helper_page_flip,871 .page_flip = drm_atomic_helper_page_flip,
878 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state,872 .atomic_duplicate_state = ast_crtc_atomic_duplicate_state,
@@ -882,27 +876,19 @@ static const struct drm_crtc_funcs ast_crtc_funcs = { · 3 unmodified lines
882static int ast_crtc_init(struct drm_device *dev)876static int ast_crtc_init(struct drm_device *dev)
883{877{
884 struct ast_private *ast = to_ast_private(dev);878 struct ast_private *ast = to_ast_private(dev);
885 struct drm_crtc *crtc;879 struct drm_crtc *crtc = &ast->crtc;
886 int ret;880 int ret;
887 881
888 crtc = kzalloc(sizeof(*crtc), GFP_KERNEL);
889 if (!crtc)
890 return -ENOMEM;
891
892 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,882 ret = drm_crtc_init_with_planes(dev, crtc, &ast->primary_plane,
893 &ast->cursor_plane, &ast_crtc_funcs,883 &ast->cursor_plane, &ast_crtc_funcs,
894 NULL);884 NULL);
895 if (ret)885 if (ret)
896 goto err_kfree;886 return ret;
897 887
898 drm_mode_crtc_set_gamma_size(crtc, 256);888 drm_mode_crtc_set_gamma_size(crtc, 256);
899 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);889 drm_crtc_helper_add(crtc, &ast_crtc_helper_funcs);
900 890
901 return 0;891 return 0;
902
903err_kfree:
904 kfree(crtc);
905 return ret;
906}892}
907 893
908/*894/*
@@ -1021,7 +1007,6 @@ static void ast_connector_destroy(struct drm_connector *connector) · 112 unmodified lines
1021 struct ast_connector *ast_connector = to_ast_connector(connector);1007 struct ast_connector *ast_connector = to_ast_connector(connector);
1022 ast_i2c_destroy(ast_connector->i2c);1008 ast_i2c_destroy(ast_connector->i2c);
1023 drm_connector_cleanup(connector);1009 drm_connector_cleanup(connector);
1024 kfree(connector);
1025}1010}
1026 1011
1027static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {1012static const struct drm_connector_helper_funcs ast_connector_helper_funcs = {
@@ -1039,15 +1024,11 @@ static const struct drm_connector_funcs ast_connector_funcs = { · 11 unmodified lines
1039 1024
1040static int ast_connector_init(struct drm_device *dev)1025static int ast_connector_init(struct drm_device *dev)
1041{1026{
1042 struct ast_connector *ast_connector;1027 struct ast_private *ast = to_ast_private(dev);
1043 struct drm_connector *connector;1028 struct ast_connector *ast_connector = &ast->connector;
1044 struct drm_encoder *encoder;1029 struct drm_connector *connector = &ast_connector->base;
1045 1030 struct drm_encoder *encoder = &ast->encoder;
1046 ast_connector = kzalloc(sizeof(struct ast_connector), GFP_KERNEL);
1047 if (!ast_connector)
1048 return -ENOMEM;
1049 1031
1050 connector = &ast_connector->base;
1051 ast_connector->i2c = ast_i2c_create(dev);1032 ast_connector->i2c = ast_i2c_create(dev);
1052 if (!ast_connector->i2c)1033 if (!ast_connector->i2c)
1053 drm_err(dev, "failed to add ddc bus for connector\n");1034 drm_err(dev, "failed to add ddc bus for connector\n");
@@ -1064,7 +1045,6 @@ static int ast_connector_init(struct drm_device *dev) · 10 unmodified lines
1064 1045
1065 connector->polled = DRM_CONNECTOR_POLL_CONNECT;1046 connector->polled = DRM_CONNECTOR_POLL_CONNECT;
1066 1047
1067 encoder = list_first_entry(&dev->mode_config.encoder_list, struct drm_encoder, head);
1068 drm_connector_attach_encoder(connector, encoder);1048 drm_connector_attach_encoder(connector, encoder);
1069 1049
1070 return 0;1050 return 0;
@@ -1083,7 +1063,7 @@ static const struct drm_mode_config_funcs ast_mode_config_funcs = { · 12 unmodified lines
1083 1063
1084int ast_mode_config_init(struct ast_private *ast)1064int ast_mode_config_init(struct ast_private *ast)
1085{1065{
1086 struct drm_device *dev = ast->dev;1066 struct drm_device *dev = &ast->base;
1087 int ret;1067 int ret;
1088 1068
1089 ret = ast_cursor_init(ast);1069 ret = ast_cursor_init(ast);
@@ -1099,7 +1079,7 @@ int ast_mode_config_init(struct ast_private *ast) · 9 unmodified lines
1099 dev->mode_config.min_height = 0;1079 dev->mode_config.min_height = 0;
1100 dev->mode_config.preferred_depth = 24;1080 dev->mode_config.preferred_depth = 24;
1101 dev->mode_config.prefer_shadow = 1;1081 dev->mode_config.prefer_shadow = 1;
1102 dev->mode_config.fb_base = pci_resource_start(ast->dev->pdev, 0);1082 dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
1103 1083
1104 if (ast->chip == AST2100 ||1084 if (ast->chip == AST2100 ||
1105 ast->chip == AST2200 ||1085 ast->chip == AST2200 ||
drivers/gpu/drm/ast/ast_post.c+3−3
@@ -365,12 +365,12 @@ static void ast_init_dram_reg(struct drm_device *dev) · 364 unmodified lines
365 365
366void ast_post_gpu(struct drm_device *dev)366void ast_post_gpu(struct drm_device *dev)
367{367{
368 u32 reg;
369 struct ast_private *ast = to_ast_private(dev);368 struct ast_private *ast = to_ast_private(dev);
369 u32 reg;
370 370
371 pci_read_config_dword(ast->dev->pdev, 0x04, &reg);371 pci_read_config_dword(dev->pdev, 0x04, &reg);
372 reg |= 0x3;372 reg |= 0x3;
373 pci_write_config_dword(ast->dev->pdev, 0x04, reg);373 pci_write_config_dword(dev->pdev, 0x04, reg);
374 374
375 ast_enable_vga(dev);375 ast_enable_vga(dev);
376 ast_open_key(ast);376 ast_open_key(ast);
drivers/gpu/drm/bridge/Kconfig+31−0
@@ -48,6 +48,19 @@ config DRM_DISPLAY_CONNECTOR · 47 unmodified lines
48 on ARM-based platforms. Saying Y here when this driver is not needed48 on ARM-based platforms. Saying Y here when this driver is not needed
49 will not cause any issue.49 will not cause any issue.
50 50
51config DRM_LONTIUM_LT9611
52 tristate "Lontium LT9611 DSI/HDMI bridge"
53 select SND_SOC_HDMI_CODEC if SND_SOC
54 depends on OF
55 select DRM_PANEL_BRIDGE
56 select DRM_KMS_HELPER
57 select REGMAP_I2C
58 help
59 Driver for Lontium LT9611 DSI to HDMI bridge
60 chip driver that converts dual DSI and I2S to
61 HDMI signals
62 Please say Y if you have such hardware.
63
51config DRM_LVDS_CODEC64config DRM_LVDS_CODEC
52 tristate "Transparent LVDS encoders and decoders support"65 tristate "Transparent LVDS encoders and decoders support"
53 depends on OF66 depends on OF
@@ -153,6 +166,14 @@ config DRM_THINE_THC63LVD1024 · 99 unmodified lines
153 help166 help
154 Thine THC63LVD1024 LVDS/parallel converter driver.167 Thine THC63LVD1024 LVDS/parallel converter driver.
155 168
169config DRM_TOSHIBA_TC358762
170 tristate "TC358762 DSI/DPI bridge"
171 depends on OF
172 select DRM_MIPI_DSI
173 select DRM_PANEL_BRIDGE
174 help
175 Toshiba TC358762 DSI/DPI bridge driver.
176
156config DRM_TOSHIBA_TC358764177config DRM_TOSHIBA_TC358764
157 tristate "TC358764 DSI/LVDS bridge"178 tristate "TC358764 DSI/LVDS bridge"
158 depends on OF179 depends on OF
@@ -181,6 +202,16 @@ config DRM_TOSHIBA_TC358768 · 22 unmodified lines
181 help202 help
182 Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver.203 Toshiba TC358768AXBG/TC358778XBG DSI bridge chip driver.
183 204
205config DRM_TOSHIBA_TC358775
206 tristate "Toshiba TC358775 DSI/LVDS bridge"
207 depends on OF
208 select DRM_KMS_HELPER
209 select REGMAP_I2C
210 select DRM_PANEL
211 select DRM_MIPI_DSI
212 help
213 Toshiba TC358775 DSI/LVDS bridge chip driver.
214
184config DRM_TI_TFP410215config DRM_TI_TFP410
185 tristate "TI TFP410 DVI/HDMI bridge"216 tristate "TI TFP410 DVI/HDMI bridge"
186 depends on OF217 depends on OF
drivers/gpu/drm/bridge/Makefile+3−0
@@ -2,6 +2,7 @@ · 1 unmodified line
2obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o2obj-$(CONFIG_DRM_CDNS_DSI) += cdns-dsi.o
3obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o3obj-$(CONFIG_DRM_CHRONTEL_CH7033) += chrontel-ch7033.o
4obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o4obj-$(CONFIG_DRM_DISPLAY_CONNECTOR) += display-connector.o
5obj-$(CONFIG_DRM_LONTIUM_LT9611) += lontium-lt9611.o
5obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o6obj-$(CONFIG_DRM_LVDS_CODEC) += lvds-codec.o
6obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o7obj-$(CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW) += megachips-stdpxxxx-ge-b850v3-fw.o
7obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o8obj-$(CONFIG_DRM_NXP_PTN3460) += nxp-ptn3460.o
@@ -12,9 +13,11 @@ obj-$(CONFIG_DRM_SII902X) += sii902x.o · 4 unmodified lines
12obj-$(CONFIG_DRM_SII9234) += sii9234.o13obj-$(CONFIG_DRM_SII9234) += sii9234.o
13obj-$(CONFIG_DRM_SIMPLE_BRIDGE) += simple-bridge.o14obj-$(CONFIG_DRM_SIMPLE_BRIDGE) += simple-bridge.o
14obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o15obj-$(CONFIG_DRM_THINE_THC63LVD1024) += thc63lvd1024.o
16obj-$(CONFIG_DRM_TOSHIBA_TC358762) += tc358762.o
15obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o17obj-$(CONFIG_DRM_TOSHIBA_TC358764) += tc358764.o
16obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o18obj-$(CONFIG_DRM_TOSHIBA_TC358767) += tc358767.o
17obj-$(CONFIG_DRM_TOSHIBA_TC358768) += tc358768.o19obj-$(CONFIG_DRM_TOSHIBA_TC358768) += tc358768.o
20obj-$(CONFIG_DRM_TOSHIBA_TC358775) += tc358775.o
18obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/21obj-$(CONFIG_DRM_I2C_ADV7511) += adv7511/
19obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o22obj-$(CONFIG_DRM_TI_SN65DSI86) += ti-sn65dsi86.o
20obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o23obj-$(CONFIG_DRM_TI_TFP410) += ti-tfp410.o
drivers/gpu/drm/bridge/analogix/analogix-anx6345.c+0−12
@@ -507,10 +507,6 @@ static const struct drm_connector_helper_funcs anx6345_connector_helper_funcs = · 506 unmodified lines
507static void507static void
508anx6345_connector_destroy(struct drm_connector *connector)508anx6345_connector_destroy(struct drm_connector *connector)
509{509{
510 struct anx6345 *anx6345 = connector_to_anx6345(connector);
511
512 if (anx6345->panel)
513 drm_panel_detach(anx6345->panel);
514 drm_connector_cleanup(connector);510 drm_connector_cleanup(connector);
515}511}
516 512
@@ -575,14 +571,6 @@ static int anx6345_bridge_attach(struct drm_bridge *bridge, · 58 unmodified lines
575 return err;571 return err;
576 }572 }
577 573
578 if (anx6345->panel) {
579 err = drm_panel_attach(anx6345->panel, &anx6345->connector);
580 if (err) {
581 DRM_ERROR("Failed to attach panel: %d\n", err);
582 return err;
583 }
584 }
585
586 return 0;574 return 0;
587}575}
588 576
drivers/gpu/drm/bridge/analogix/analogix_dp_core.c+0−9
@@ -1265,14 +1265,6 @@ static int analogix_dp_bridge_attach(struct drm_bridge *bridge, · 1264 unmodified lines
1265 }1265 }
1266 }1266 }
1267 1267
1268 if (dp->plat_data->panel) {
1269 ret = drm_panel_attach(dp->plat_data->panel, &dp->connector);
1270 if (ret) {
1271 DRM_ERROR("Failed to attach panel\n");
1272 return ret;
1273 }
1274 }
1275
1276 return 0;1268 return 0;
1277}1269}
1278 1270
@@ -1803,7 +1795,6 @@ void analogix_dp_unbind(struct analogix_dp_device *dp) · 524 unmodified lines
1803 if (dp->plat_data->panel) {1795 if (dp->plat_data->panel) {
1804 if (drm_panel_unprepare(dp->plat_data->panel))1796 if (drm_panel_unprepare(dp->plat_data->panel))
1805 DRM_ERROR("failed to turnoff the panel\n");1797 DRM_ERROR("failed to turnoff the panel\n");
1806 drm_panel_detach(dp->plat_data->panel);
1807 }1798 }
1808 1799
1809 drm_dp_aux_unregister(&dp->aux);1800 drm_dp_aux_unregister(&dp->aux);
drivers/gpu/drm/bridge/lontium-lt9611.c+1230−0
@@ -0,0 +1,1230 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
4 * Copyright (c) 2019-2020. Linaro Limited.
5 */
6
7#include <linux/gpio/consumer.h>
8#include <linux/interrupt.h>
9#include <linux/module.h>
10#include <linux/of_graph.h>
11#include <linux/platform_device.h>
12#include <linux/regmap.h>
13#include <linux/regulator/consumer.h>
14
15#include <sound/hdmi-codec.h>
16
17#include <drm/drm_atomic_helper.h>
18#include <drm/drm_bridge.h>
19#include <drm/drm_mipi_dsi.h>
20#include <drm/drm_print.h>
21#include <drm/drm_probe_helper.h>
22
23#define EDID_SEG_SIZE 256
24#define EDID_LEN 32
25#define EDID_LOOP 8
26#define KEY_DDC_ACCS_DONE 0x02
27#define DDC_NO_ACK 0x50
28
29#define LT9611_4LANES 0
30
31struct lt9611 {
32 struct device *dev;
33 struct drm_bridge bridge;
34 struct drm_connector connector;
35
36 struct regmap *regmap;
37
38 struct device_node *dsi0_node;
39 struct device_node *dsi1_node;
40 struct mipi_dsi_device *dsi0;
41 struct mipi_dsi_device *dsi1;
42 struct platform_device *audio_pdev;
43
44 bool ac_mode;
45
46 struct gpio_desc *reset_gpio;
47 struct gpio_desc *enable_gpio;
48
49 bool power_on;
50 bool sleep;
51
52 struct regulator_bulk_data supplies[2];
53
54 struct i2c_client *client;
55
56 enum drm_connector_status status;
57
58 u8 edid_buf[EDID_SEG_SIZE];
59 u32 vic;
60};
61
62#define LT9611_PAGE_CONTROL 0xff
63
64static const struct regmap_range_cfg lt9611_ranges[] = {
65 {
66 .name = "register_range",
67 .range_min = 0,
68 .range_max = 0x85ff,
69 .selector_reg = LT9611_PAGE_CONTROL,
70 .selector_mask = 0xff,
71 .selector_shift = 0,
72 .window_start = 0,
73 .window_len = 0x100,
74 },
75};
76
77static const struct regmap_config lt9611_regmap_config = {
78 .reg_bits = 8,
79 .val_bits = 8,
80 .max_register = 0xffff,
81 .ranges = lt9611_ranges,
82 .num_ranges = ARRAY_SIZE(lt9611_ranges),
83};
84
85struct lt9611_mode {
86 u16 hdisplay;
87 u16 vdisplay;
88 u8 vrefresh;
89 u8 lanes;
90 u8 intfs;
91};
92
93static struct lt9611_mode lt9611_modes[] = {
94 { 3840, 2160, 30, 4, 2 }, /* 3840x2160 24bit 30Hz 4Lane 2ports */
95 { 1920, 1080, 60, 4, 1 }, /* 1080P 24bit 60Hz 4lane 1port */
96 { 1920, 1080, 30, 3, 1 }, /* 1080P 24bit 30Hz 3lane 1port */
97 { 1920, 1080, 24, 3, 1 },
98 { 720, 480, 60, 4, 1 },
99 { 720, 576, 50, 2, 1 },
100 { 640, 480, 60, 2, 1 },
101};
102
103static struct lt9611 *bridge_to_lt9611(struct drm_bridge *bridge)
104{
105 return container_of(bridge, struct lt9611, bridge);
106}
107
108static struct lt9611 *connector_to_lt9611(struct drm_connector *connector)
109{
110 return container_of(connector, struct lt9611, connector);
111}
112
113static int lt9611_mipi_input_analog(struct lt9611 *lt9611)
114{
115 const struct reg_sequence reg_cfg[] = {
116 { 0x8106, 0x40 }, /* port A rx current */
117 { 0x810a, 0xfe }, /* port A ldo voltage set */
118 { 0x810b, 0xbf }, /* enable port A lprx */
119 { 0x8111, 0x40 }, /* port B rx current */
120 { 0x8115, 0xfe }, /* port B ldo voltage set */
121 { 0x8116, 0xbf }, /* enable port B lprx */
122
123 { 0x811c, 0x03 }, /* PortA clk lane no-LP mode */
124 { 0x8120, 0x03 }, /* PortB clk lane with-LP mode */
125 };
126
127 return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
128}
129
130static int lt9611_mipi_input_digital(struct lt9611 *lt9611,
131 const struct drm_display_mode *mode)
132{
133 struct reg_sequence reg_cfg[] = {
134 { 0x8300, LT9611_4LANES },
135 { 0x830a, 0x00 },
136 { 0x824f, 0x80 },
137 { 0x8250, 0x10 },
138 { 0x8302, 0x0a },
139 { 0x8306, 0x0a },
140 };
141
142 if (mode->hdisplay == 3840)
143 reg_cfg[1].def = 0x03;
144
145 return regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
146}
147
148static void lt9611_mipi_video_setup(struct lt9611 *lt9611,
149 const struct drm_display_mode *mode)
150{
151 u32 h_total, hactive, hsync_len, hfront_porch, hsync_porch;
152 u32 v_total, vactive, vsync_len, vfront_porch, vsync_porch;
153
154 h_total = mode->htotal;
155 v_total = mode->vtotal;
156
157 hactive = mode->hdisplay;
158 hsync_len = mode->hsync_end - mode->hsync_start;
159 hfront_porch = mode->hsync_start - mode->hdisplay;
160 hsync_porch = hsync_len + mode->htotal - mode->hsync_end;
161
162 vactive = mode->vdisplay;
163 vsync_len = mode->vsync_end - mode->vsync_start;
164 vfront_porch = mode->vsync_start - mode->vdisplay;
165 vsync_porch = vsync_len + mode->vtotal - mode->vsync_end;
166
167 regmap_write(lt9611->regmap, 0x830d, (u8)(v_total / 256));
168 regmap_write(lt9611->regmap, 0x830e, (u8)(v_total % 256));
169
170 regmap_write(lt9611->regmap, 0x830f, (u8)(vactive / 256));
171 regmap_write(lt9611->regmap, 0x8310, (u8)(vactive % 256));
172
173 regmap_write(lt9611->regmap, 0x8311, (u8)(h_total / 256));
174 regmap_write(lt9611->regmap, 0x8312, (u8)(h_total % 256));
175
176 regmap_write(lt9611->regmap, 0x8313, (u8)(hactive / 256));
177 regmap_write(lt9611->regmap, 0x8314, (u8)(hactive % 256));
178
179 regmap_write(lt9611->regmap, 0x8315, (u8)(vsync_len % 256));
180 regmap_write(lt9611->regmap, 0x8316, (u8)(hsync_len % 256));
181
182 regmap_write(lt9611->regmap, 0x8317, (u8)(vfront_porch % 256));
183
184 regmap_write(lt9611->regmap, 0x8318, (u8)(vsync_porch % 256));
185
186 regmap_write(lt9611->regmap, 0x8319, (u8)(hfront_porch % 256));
187
188 regmap_write(lt9611->regmap, 0x831a, (u8)(hsync_porch / 256));
189 regmap_write(lt9611->regmap, 0x831b, (u8)(hsync_porch % 256));
190}
191
192static void lt9611_pcr_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
193{
194 const struct reg_sequence reg_cfg[] = {
195 { 0x830b, 0x01 },
196 { 0x830c, 0x10 },
197 { 0x8348, 0x00 },
198 { 0x8349, 0x81 },
199
200 /* stage 1 */
201 { 0x8321, 0x4a },
202 { 0x8324, 0x71 },
203 { 0x8325, 0x30 },
204 { 0x832a, 0x01 },
205
206 /* stage 2 */
207 { 0x834a, 0x40 },
208 { 0x831d, 0x10 },
209
210 /* MK limit */
211 { 0x832d, 0x38 },
212 { 0x8331, 0x08 },
213 };
214 const struct reg_sequence reg_cfg2[] = {
215 { 0x830b, 0x03 },
216 { 0x830c, 0xd0 },
217 { 0x8348, 0x03 },
218 { 0x8349, 0xe0 },
219 { 0x8324, 0x72 },
220 { 0x8325, 0x00 },
221 { 0x832a, 0x01 },
222 { 0x834a, 0x10 },
223 { 0x831d, 0x10 },
224 { 0x8326, 0x37 },
225 };
226
227 regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
228
229 switch (mode->hdisplay) {
230 case 640:
231 regmap_write(lt9611->regmap, 0x8326, 0x14);
232 break;
233 case 1920:
234 regmap_write(lt9611->regmap, 0x8326, 0x37);
235 break;
236 case 3840:
237 regmap_multi_reg_write(lt9611->regmap, reg_cfg2, ARRAY_SIZE(reg_cfg2));
238 break;
239 }
240
241 /* pcr rst */
242 regmap_write(lt9611->regmap, 0x8011, 0x5a);
243 regmap_write(lt9611->regmap, 0x8011, 0xfa);
244}
245
246static int lt9611_pll_setup(struct lt9611 *lt9611, const struct drm_display_mode *mode)
247{
248 unsigned int pclk = mode->clock;
249 const struct reg_sequence reg_cfg[] = {
250 /* txpll init */
251 { 0x8123, 0x40 },
252 { 0x8124, 0x64 },
253 { 0x8125, 0x80 },
254 { 0x8126, 0x55 },
255 { 0x812c, 0x37 },
256 { 0x812f, 0x01 },
257 { 0x8126, 0x55 },
258 { 0x8127, 0x66 },
259 { 0x8128, 0x88 },
260 };
261
262 regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
263
264 if (pclk > 150000)
265 regmap_write(lt9611->regmap, 0x812d, 0x88);
266 else if (pclk > 70000)
267 regmap_write(lt9611->regmap, 0x812d, 0x99);
268 else
269 regmap_write(lt9611->regmap, 0x812d, 0xaa);
270
271 /*
272 * first divide pclk by 2 first
273 * - write divide by 64k to 19:16 bits which means shift by 17
274 * - write divide by 256 to 15:8 bits which means shift by 9
275 * - write remainder to 7:0 bits, which means shift by 1
276 */
277 regmap_write(lt9611->regmap, 0x82e3, pclk >> 17); /* pclk[19:16] */
278 regmap_write(lt9611->regmap, 0x82e4, pclk >> 9); /* pclk[15:8] */
279 regmap_write(lt9611->regmap, 0x82e5, pclk >> 1); /* pclk[7:0] */
280
281 regmap_write(lt9611->regmap, 0x82de, 0x20);
282 regmap_write(lt9611->regmap, 0x82de, 0xe0);
283
284 regmap_write(lt9611->regmap, 0x8016, 0xf1);
285 regmap_write(lt9611->regmap, 0x8016, 0xf3);
286
287 return 0;
288}
289
290static int lt9611_read_video_check(struct lt9611 *lt9611, unsigned int reg)
291{
292 unsigned int temp, temp2;
293 int ret;
294
295 ret = regmap_read(lt9611->regmap, reg, &temp);
296 if (ret)
297 return ret;
298 temp <<= 8;
299 ret = regmap_read(lt9611->regmap, reg + 1, &temp2);
300 if (ret)
301 return ret;
302
303 return (temp + temp2);
304}
305
306static int lt9611_video_check(struct lt9611 *lt9611)
307{
308 u32 v_total, vactive, hactive_a, hactive_b, h_total_sysclk;
309 int temp;
310
311 /* top module video check */
312
313 /* vactive */
314 temp = lt9611_read_video_check(lt9611, 0x8282);
315 if (temp < 0)
316 goto end;
317 vactive = temp;
318
319 /* v_total */
320 temp = lt9611_read_video_check(lt9611, 0x826c);
321 if (temp < 0)
322 goto end;
323 v_total = temp;
324
325 /* h_total_sysclk */
326 temp = lt9611_read_video_check(lt9611, 0x8286);
327 if (temp < 0)
328 goto end;
329 h_total_sysclk = temp;
330
331 /* hactive_a */
332 temp = lt9611_read_video_check(lt9611, 0x8382);
333 if (temp < 0)
334 goto end;
335 hactive_a = temp / 3;
336
337 /* hactive_b */
338 temp = lt9611_read_video_check(lt9611, 0x8386);
339 if (temp < 0)
340 goto end;
341 hactive_b = temp / 3;
342
343 dev_info(lt9611->dev,
344 "video check: hactive_a=%d, hactive_b=%d, vactive=%d, v_total=%d, h_total_sysclk=%d\n",
345 hactive_a, hactive_b, vactive, v_total, h_total_sysclk);
346
347 return 0;
348
349end:
350 dev_err(lt9611->dev, "read video check error\n");
351 return temp;
352}
353
354static void lt9611_hdmi_tx_digital(struct lt9611 *lt9611)
355{
356 regmap_write(lt9611->regmap, 0x8443, 0x46 - lt9611->vic);
357 regmap_write(lt9611->regmap, 0x8447, lt9611->vic);
358 regmap_write(lt9611->regmap, 0x843d, 0x0a); /* UD1 infoframe */
359
360 regmap_write(lt9611->regmap, 0x82d6, 0x8c);
361 regmap_write(lt9611->regmap, 0x82d7, 0x04);
362}
363
364static void lt9611_hdmi_tx_phy(struct lt9611 *lt9611)
365{
366 struct reg_sequence reg_cfg[] = {
367 { 0x8130, 0x6a },
368 { 0x8131, 0x44 }, /* HDMI DC mode */
369 { 0x8132, 0x4a },
370 { 0x8133, 0x0b },
371 { 0x8134, 0x00 },
372 { 0x8135, 0x00 },
373 { 0x8136, 0x00 },
374 { 0x8137, 0x44 },
375 { 0x813f, 0x0f },
376 { 0x8140, 0xa0 },
377 { 0x8141, 0xa0 },
378 { 0x8142, 0xa0 },
379 { 0x8143, 0xa0 },
380 { 0x8144, 0x0a },
381 };
382
383 /* HDMI AC mode */
384 if (lt9611->ac_mode)
385 reg_cfg[2].def = 0x73;
386
387 regmap_multi_reg_write(lt9611->regmap, reg_cfg, ARRAY_SIZE(reg_cfg));
388}
389
390static irqreturn_t lt9611_irq_thread_handler(int irq, void *dev_id)
391{
392 struct lt9611 *lt9611 = dev_id;
393 unsigned int irq_flag0 = 0;
394 unsigned int irq_flag3 = 0;
395
396 regmap_read(lt9611->regmap, 0x820f, &irq_flag3);
397 regmap_read(lt9611->regmap, 0x820c, &irq_flag0);
398
399 /* hpd changed low */
400 if (irq_flag3 & 0x80) {
401 dev_info(lt9611->dev, "hdmi cable disconnected\n");
402
403 regmap_write(lt9611->regmap, 0x8207, 0xbf);
404 regmap_write(lt9611->regmap, 0x8207, 0x3f);
405 }
406
407 /* hpd changed high */
408 if (irq_flag3 & 0x40) {
409 dev_info(lt9611->dev, "hdmi cable connected\n");
410
411 regmap_write(lt9611->regmap, 0x8207, 0x7f);
412 regmap_write(lt9611->regmap, 0x8207, 0x3f);
413 }
414
415 if (irq_flag3 & 0xc0 && lt9611->bridge.dev)
416 drm_kms_helper_hotplug_event(lt9611->bridge.dev);
417
418 /* video input changed */
419 if (irq_flag0 & 0x01) {
420 dev_info(lt9611->dev, "video input changed\n");
421 regmap_write(lt9611->regmap, 0x829e, 0xff);
422 regmap_write(lt9611->regmap, 0x829e, 0xf7);
423 regmap_write(lt9611->regmap, 0x8204, 0xff);
424 regmap_write(lt9611->regmap, 0x8204, 0xfe);
425 }
426
427 return IRQ_HANDLED;
428}
429
430static void lt9611_enable_hpd_interrupts(struct lt9611 *lt9611)
431{
432 unsigned int val;
433
434 regmap_read(lt9611->regmap, 0x8203, &val);
435
436 val &= ~0xc0;
437 regmap_write(lt9611->regmap, 0x8203, val);
438 regmap_write(lt9611->regmap, 0x8207, 0xff); /* clear */
439 regmap_write(lt9611->regmap, 0x8207, 0x3f);
440}
441
442static void lt9611_sleep_setup(struct lt9611 *lt9611)
443{
444 const struct reg_sequence sleep_setup[] = {
445 { 0x8024, 0x76 },
446 { 0x8023, 0x01 },
447 { 0x8157, 0x03 }, /* set addr pin as output */
448 { 0x8149, 0x0b },
449 { 0x8151, 0x30 }, /* disable IRQ */
450 { 0x8102, 0x48 }, /* MIPI Rx power down */
451 { 0x8123, 0x80 },
452 { 0x8130, 0x00 },
453 { 0x8100, 0x01 }, /* bandgap power down */
454 { 0x8101, 0x00 }, /* system clk power down */
455 };
456
457 regmap_multi_reg_write(lt9611->regmap,
458 sleep_setup, ARRAY_SIZE(sleep_setup));
459 lt9611->sleep = true;
460}
461
462static int lt9611_power_on(struct lt9611 *lt9611)
463{
464 int ret;
465 const struct reg_sequence seq[] = {
466 /* LT9611_System_Init */
467 { 0x8101, 0x18 }, /* sel xtal clock */
468
469 /* timer for frequency meter */
470 { 0x821b, 0x69 }, /* timer 2 */
471 { 0x821c, 0x78 },
472 { 0x82cb, 0x69 }, /* timer 1 */
473 { 0x82cc, 0x78 },
474
475 /* irq init */
476 { 0x8251, 0x01 },
477 { 0x8258, 0x0a }, /* hpd irq */
478 { 0x8259, 0x80 }, /* hpd debounce width */
479 { 0x829e, 0xf7 }, /* video check irq */
480
481 /* power consumption for work */
482 { 0x8004, 0xf0 },
483 { 0x8006, 0xf0 },
484 { 0x800a, 0x80 },
485 { 0x800b, 0x40 },
486 { 0x800d, 0xef },
487 { 0x8011, 0xfa },
488 };
489
490 if (lt9611->power_on)
491 return 0;
492
493 ret = regmap_multi_reg_write(lt9611->regmap, seq, ARRAY_SIZE(seq));
494 if (!ret)
495 lt9611->power_on = true;
496
497 return ret;
498}
499
500static int lt9611_power_off(struct lt9611 *lt9611)
501{
502 int ret;
503
504 ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
505 if (!ret)
506 lt9611->power_on = false;
507
508 return ret;
509}
510
511static void lt9611_reset(struct lt9611 *lt9611)
512{
513 gpiod_set_value_cansleep(lt9611->reset_gpio, 1);
514 msleep(20);
515
516 gpiod_set_value_cansleep(lt9611->reset_gpio, 0);
517 msleep(20);
518
519 gpiod_set_value_cansleep(lt9611->reset_gpio, 1);
520 msleep(100);
521}
522
523static void lt9611_assert_5v(struct lt9611 *lt9611)
524{
525 if (!lt9611->enable_gpio)
526 return;
527
528 gpiod_set_value_cansleep(lt9611->enable_gpio, 1);
529 msleep(20);
530}
531
532static int lt9611_regulator_init(struct lt9611 *lt9611)
533{
534 int ret;
535
536 lt9611->supplies[0].supply = "vdd";
537 lt9611->supplies[1].supply = "vcc";
538
539 ret = devm_regulator_bulk_get(lt9611->dev, 2, lt9611->supplies);
540 if (ret < 0)
541 return ret;
542
543 return regulator_set_load(lt9611->supplies[0].consumer, 300000);
544}
545
546static int lt9611_regulator_enable(struct lt9611 *lt9611)
547{
548 int ret;
549
550 ret = regulator_enable(lt9611->supplies[0].consumer);
551 if (ret < 0)
552 return ret;
553
554 usleep_range(1000, 10000);
555
556 ret = regulator_enable(lt9611->supplies[1].consumer);
557 if (ret < 0) {
558 regulator_disable(lt9611->supplies[0].consumer);
559 return ret;
560 }
561
562 return 0;
563}
564
565static struct lt9611_mode *lt9611_find_mode(const struct drm_display_mode *mode)
566{
567 int i;
568
569 for (i = 0; i < ARRAY_SIZE(lt9611_modes); i++) {
570 if (lt9611_modes[i].hdisplay == mode->hdisplay &&
571 lt9611_modes[i].vdisplay == mode->vdisplay &&
572 lt9611_modes[i].vrefresh == drm_mode_vrefresh(mode)) {
573 return &lt9611_modes[i];
574 }
575 }
576
577 return NULL;
578}
579
580/* connector funcs */
581static enum drm_connector_status
582lt9611_connector_detect(struct drm_connector *connector, bool force)
583{
584 struct lt9611 *lt9611 = connector_to_lt9611(connector);
585 unsigned int reg_val = 0;
586 int connected = 0;
587
588 regmap_read(lt9611->regmap, 0x825e, &reg_val);
589 connected = (reg_val & BIT(2));
590
591 lt9611->status = connected ? connector_status_connected :
592 connector_status_disconnected;
593
594 return lt9611->status;
595}
596
597static int lt9611_read_edid(struct lt9611 *lt9611)
598{
599 unsigned int temp;
600 int ret = 0;
601 int i, j;
602
603 /* memset to clear old buffer, if any */
604 memset(lt9611->edid_buf, 0, sizeof(lt9611->edid_buf));
605
606 regmap_write(lt9611->regmap, 0x8503, 0xc9);
607
608 /* 0xA0 is EDID device address */
609 regmap_write(lt9611->regmap, 0x8504, 0xa0);
610 /* 0x00 is EDID offset address */
611 regmap_write(lt9611->regmap, 0x8505, 0x00);
612
613 /* length for read */
614 regmap_write(lt9611->regmap, 0x8506, EDID_LEN);
615 regmap_write(lt9611->regmap, 0x8514, 0x7f);
616
617 for (i = 0; i < EDID_LOOP; i++) {
618 /* offset address */
619 regmap_write(lt9611->regmap, 0x8505, i * EDID_LEN);
620 regmap_write(lt9611->regmap, 0x8507, 0x36);
621 regmap_write(lt9611->regmap, 0x8507, 0x31);
622 regmap_write(lt9611->regmap, 0x8507, 0x37);
623 usleep_range(5000, 10000);
624
625 regmap_read(lt9611->regmap, 0x8540, &temp);
626
627 if (temp & KEY_DDC_ACCS_DONE) {
628 for (j = 0; j < EDID_LEN; j++) {
629 regmap_read(lt9611->regmap, 0x8583, &temp);
630 lt9611->edid_buf[i * EDID_LEN + j] = temp;
631 }
632
633 } else if (temp & DDC_NO_ACK) { /* DDC No Ack or Abitration lost */
634 dev_err(lt9611->dev, "read edid failed: no ack\n");
635 ret = -EIO;
636 goto end;
637
638 } else {
639 dev_err(lt9611->dev, "read edid failed: access not done\n");
640 ret = -EIO;
641 goto end;
642 }
643 }
644
645end:
646 regmap_write(lt9611->regmap, 0x8507, 0x1f);
647 return ret;
648}
649
650static int
651lt9611_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
652{
653 struct lt9611 *lt9611 = data;
654 int ret;
655
656 if (len > 128)
657 return -EINVAL;
658
659 /* supports up to 1 extension block */
660 /* TODO: add support for more extension blocks */
661 if (block > 1)
662 return -EINVAL;
663
664 if (block == 0) {
665 ret = lt9611_read_edid(lt9611);
666 if (ret) {
667 dev_err(lt9611->dev, "edid read failed\n");
668 return ret;
669 }
670 }
671
672 block %= 2;
673 memcpy(buf, lt9611->edid_buf + (block * 128), len);
674
675 return 0;
676}
677
678static int lt9611_connector_get_modes(struct drm_connector *connector)
679{
680 struct lt9611 *lt9611 = connector_to_lt9611(connector);
681 unsigned int count;
682 struct edid *edid;
683
684 lt9611_power_on(lt9611);
685 edid = drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
686 drm_connector_update_edid_property(connector, edid);
687 count = drm_add_edid_modes(connector, edid);
688 kfree(edid);
689
690 return count;
691}
692
693static enum drm_mode_status
694lt9611_connector_mode_valid(struct drm_connector *connector,
695 struct drm_display_mode *mode)
696{
697 struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
698
699 return lt9611_mode ? MODE_OK : MODE_BAD;
700}
701
702/* bridge funcs */
703static void lt9611_bridge_enable(struct drm_bridge *bridge)
704{
705 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
706
707 if (lt9611_power_on(lt9611)) {
708 dev_err(lt9611->dev, "power on failed\n");
709 return;
710 }
711
712 lt9611_mipi_input_analog(lt9611);
713 lt9611_hdmi_tx_digital(lt9611);
714 lt9611_hdmi_tx_phy(lt9611);
715
716 msleep(500);
717
718 lt9611_video_check(lt9611);
719
720 /* Enable HDMI output */
721 regmap_write(lt9611->regmap, 0x8130, 0xea);
722}
723
724static void lt9611_bridge_disable(struct drm_bridge *bridge)
725{
726 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
727 int ret;
728
729 /* Disable HDMI output */
730 ret = regmap_write(lt9611->regmap, 0x8130, 0x6a);
731 if (ret) {
732 dev_err(lt9611->dev, "video on failed\n");
733 return;
734 }
735
736 if (lt9611_power_off(lt9611)) {
737 dev_err(lt9611->dev, "power on failed\n");
738 return;
739 }
740}
741
742static struct
743drm_connector_helper_funcs lt9611_bridge_connector_helper_funcs = {
744 .get_modes = lt9611_connector_get_modes,
745 .mode_valid = lt9611_connector_mode_valid,
746};
747
748static const struct drm_connector_funcs lt9611_bridge_connector_funcs = {
749 .fill_modes = drm_helper_probe_single_connector_modes,
750 .detect = lt9611_connector_detect,
751 .destroy = drm_connector_cleanup,
752 .reset = drm_atomic_helper_connector_reset,
753 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
754 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
755};
756
757static struct mipi_dsi_device *lt9611_attach_dsi(struct lt9611 *lt9611,
758 struct device_node *dsi_node)
759{
760 const struct mipi_dsi_device_info info = { "lt9611", 0, NULL };
761 struct mipi_dsi_device *dsi;
762 struct mipi_dsi_host *host;
763 int ret;
764
765 host = of_find_mipi_dsi_host_by_node(dsi_node);
766 if (!host) {
767 dev_err(lt9611->dev, "failed to find dsi host\n");
768 return ERR_PTR(-EPROBE_DEFER);
769 }
770
771 dsi = mipi_dsi_device_register_full(host, &info);
772 if (IS_ERR(dsi)) {
773 dev_err(lt9611->dev, "failed to create dsi device\n");
774 return dsi;
775 }
776
777 dsi->lanes = 4;
778 dsi->format = MIPI_DSI_FMT_RGB888;
779 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
780 MIPI_DSI_MODE_VIDEO_HSE;
781
782 ret = mipi_dsi_attach(dsi);
783 if (ret < 0) {
784 dev_err(lt9611->dev, "failed to attach dsi to host\n");
785 mipi_dsi_device_unregister(dsi);
786 return ERR_PTR(ret);
787 }
788
789 return dsi;
790}
791
792static void lt9611_bridge_detach(struct drm_bridge *bridge)
793{
794 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
795
796 if (lt9611->dsi1) {
797 mipi_dsi_detach(lt9611->dsi1);
798 mipi_dsi_device_unregister(lt9611->dsi1);
799 }
800
801 mipi_dsi_detach(lt9611->dsi0);
802 mipi_dsi_device_unregister(lt9611->dsi0);
803}
804
805static int lt9611_connector_init(struct drm_bridge *bridge, struct lt9611 *lt9611)
806{
807 int ret;
808
809 ret = drm_connector_init(bridge->dev, &lt9611->connector,
810 &lt9611_bridge_connector_funcs,
811 DRM_MODE_CONNECTOR_HDMIA);
812 if (ret) {
813 DRM_ERROR("Failed to initialize connector with drm\n");
814 return ret;
815 }
816
817 drm_connector_helper_add(&lt9611->connector,
818 &lt9611_bridge_connector_helper_funcs);
819 drm_connector_attach_encoder(&lt9611->connector, bridge->encoder);
820
821 if (!bridge->encoder) {
822 DRM_ERROR("Parent encoder object not found");
823 return -ENODEV;
824 }
825
826 return 0;
827}
828
829static int lt9611_bridge_attach(struct drm_bridge *bridge,
830 enum drm_bridge_attach_flags flags)
831{
832 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
833 int ret;
834
835 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)) {
836 ret = lt9611_connector_init(bridge, lt9611);
837 if (ret < 0)
838 return ret;
839 }
840
841 /* Attach primary DSI */
842 lt9611->dsi0 = lt9611_attach_dsi(lt9611, lt9611->dsi0_node);
843 if (IS_ERR(lt9611->dsi0))
844 return PTR_ERR(lt9611->dsi0);
845
846 /* Attach secondary DSI, if specified */
847 if (lt9611->dsi1_node) {
848 lt9611->dsi1 = lt9611_attach_dsi(lt9611, lt9611->dsi1_node);
849 if (IS_ERR(lt9611->dsi1)) {
850 ret = PTR_ERR(lt9611->dsi1);
851 goto err_unregister_dsi0;
852 }
853 }
854
855 return 0;
856
857err_unregister_dsi0:
858 lt9611_bridge_detach(bridge);
859 drm_connector_cleanup(&lt9611->connector);
860 mipi_dsi_device_unregister(lt9611->dsi0);
861
862 return ret;
863}
864
865static enum drm_mode_status lt9611_bridge_mode_valid(struct drm_bridge *bridge,
866 const struct drm_display_info *info,
867 const struct drm_display_mode *mode)
868{
869 struct lt9611_mode *lt9611_mode = lt9611_find_mode(mode);
870
871 return lt9611_mode ? MODE_OK : MODE_BAD;
872}
873
874static void lt9611_bridge_pre_enable(struct drm_bridge *bridge)
875{
876 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
877
878 if (!lt9611->sleep)
879 return;
880
881 lt9611_reset(lt9611);
882 regmap_write(lt9611->regmap, 0x80ee, 0x01);
883
884 lt9611->sleep = false;
885}
886
887static void lt9611_bridge_post_disable(struct drm_bridge *bridge)
888{
889 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
890
891 lt9611_sleep_setup(lt9611);
892}
893
894static void lt9611_bridge_mode_set(struct drm_bridge *bridge,
895 const struct drm_display_mode *mode,
896 const struct drm_display_mode *adj_mode)
897{
898 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
899 struct hdmi_avi_infoframe avi_frame;
900 int ret;
901
902 lt9611_bridge_pre_enable(bridge);
903
904 lt9611_mipi_input_digital(lt9611, mode);
905 lt9611_pll_setup(lt9611, mode);
906 lt9611_mipi_video_setup(lt9611, mode);
907 lt9611_pcr_setup(lt9611, mode);
908
909 ret = drm_hdmi_avi_infoframe_from_display_mode(&avi_frame,
910 &lt9611->connector,
911 mode);
912 if (!ret)
913 lt9611->vic = avi_frame.video_code;
914}
915
916static enum drm_connector_status lt9611_bridge_detect(struct drm_bridge *bridge)
917{
918 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
919 unsigned int reg_val = 0;
920 int connected;
921
922 regmap_read(lt9611->regmap, 0x825e, &reg_val);
923 connected = reg_val & BIT(2);
924
925 lt9611->status = connected ? connector_status_connected :
926 connector_status_disconnected;
927
928 return lt9611->status;
929}
930
931static struct edid *lt9611_bridge_get_edid(struct drm_bridge *bridge,
932 struct drm_connector *connector)
933{
934 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
935
936 lt9611_power_on(lt9611);
937 return drm_do_get_edid(connector, lt9611_get_edid_block, lt9611);
938}
939
940static void lt9611_bridge_hpd_enable(struct drm_bridge *bridge)
941{
942 struct lt9611 *lt9611 = bridge_to_lt9611(bridge);
943
944 lt9611_enable_hpd_interrupts(lt9611);
945}
946
947static const struct drm_bridge_funcs lt9611_bridge_funcs = {
948 .attach = lt9611_bridge_attach,
949 .detach = lt9611_bridge_detach,
950 .mode_valid = lt9611_bridge_mode_valid,
951 .enable = lt9611_bridge_enable,
952 .disable = lt9611_bridge_disable,
953 .post_disable = lt9611_bridge_post_disable,
954 .mode_set = lt9611_bridge_mode_set,
955 .detect = lt9611_bridge_detect,
956 .get_edid = lt9611_bridge_get_edid,
957 .hpd_enable = lt9611_bridge_hpd_enable,
958};
959
960static int lt9611_parse_dt(struct device *dev,
961 struct lt9611 *lt9611)
962{
963 lt9611->dsi0_node = of_graph_get_remote_node(dev->of_node, 1, -1);
964 if (!lt9611->dsi0_node) {
965 dev_err(lt9611->dev, "failed to get remote node for primary dsi\n");
966 return -ENODEV;
967 }
968
969 lt9611->dsi1_node = of_graph_get_remote_node(dev->of_node, 2, -1);
970
971 lt9611->ac_mode = of_property_read_bool(dev->of_node, "lt,ac-mode");
972
973 return 0;
974}
975
976static int lt9611_gpio_init(struct lt9611 *lt9611)
977{
978 struct device *dev = lt9611->dev;
979
980 lt9611->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
981 if (IS_ERR(lt9611->reset_gpio)) {
982 dev_err(dev, "failed to acquire reset gpio\n");
983 return PTR_ERR(lt9611->reset_gpio);
984 }
985
986 lt9611->enable_gpio = devm_gpiod_get_optional(dev, "enable",
987 GPIOD_OUT_LOW);
988 if (IS_ERR(lt9611->enable_gpio)) {
989 dev_err(dev, "failed to acquire enable gpio\n");
990 return PTR_ERR(lt9611->enable_gpio);
991 }
992
993 return 0;
994}
995
996static int lt9611_read_device_rev(struct lt9611 *lt9611)
997{
998 unsigned int rev;
999 int ret;
1000
1001 regmap_write(lt9611->regmap, 0x80ee, 0x01);
1002 ret = regmap_read(lt9611->regmap, 0x8002, &rev);
1003 if (ret)
1004 dev_err(lt9611->dev, "failed to read revision: %d\n", ret);
1005 else
1006 dev_info(lt9611->dev, "LT9611 revision: 0x%x\n", rev);
1007
1008 return ret;
1009}
1010
1011static int lt9611_hdmi_hw_params(struct device *dev, void *data,
1012 struct hdmi_codec_daifmt *fmt,
1013 struct hdmi_codec_params *hparms)
1014{
1015 struct lt9611 *lt9611 = data;
1016
1017 if (hparms->sample_rate == 48000)
1018 regmap_write(lt9611->regmap, 0x840f, 0x2b);
1019 else if (hparms->sample_rate == 96000)
1020 regmap_write(lt9611->regmap, 0x840f, 0xab);
1021 else
1022 return -EINVAL;
1023
1024 regmap_write(lt9611->regmap, 0x8435, 0x00);
1025 regmap_write(lt9611->regmap, 0x8436, 0x18);
1026 regmap_write(lt9611->regmap, 0x8437, 0x00);
1027
1028 return 0;
1029}
1030
1031static int lt9611_audio_startup(struct device *dev, void *data)
1032{
1033 struct lt9611 *lt9611 = data;
1034
1035 regmap_write(lt9611->regmap, 0x82d6, 0x8c);
1036 regmap_write(lt9611->regmap, 0x82d7, 0x04);
1037
1038 regmap_write(lt9611->regmap, 0x8406, 0x08);
1039 regmap_write(lt9611->regmap, 0x8407, 0x10);
1040
1041 regmap_write(lt9611->regmap, 0x8434, 0xd5);
1042
1043 return 0;
1044}
1045
1046static void lt9611_audio_shutdown(struct device *dev, void *data)
1047{
1048 struct lt9611 *lt9611 = data;
1049
1050 regmap_write(lt9611->regmap, 0x8406, 0x00);
1051 regmap_write(lt9611->regmap, 0x8407, 0x00);
1052}
1053
1054static int lt9611_hdmi_i2s_get_dai_id(struct snd_soc_component *component,
1055 struct device_node *endpoint)
1056{
1057 struct of_endpoint of_ep;
1058 int ret;
1059
1060 ret = of_graph_parse_endpoint(endpoint, &of_ep);
1061 if (ret < 0)
1062 return ret;
1063
1064 /*
1065 * HDMI sound should be located as reg = <2>
1066 * Then, it is sound port 0
1067 */
1068 if (of_ep.port == 2)
1069 return 0;
1070
1071 return -EINVAL;
1072}
1073
1074static const struct hdmi_codec_ops lt9611_codec_ops = {
1075 .hw_params = lt9611_hdmi_hw_params,
1076 .audio_shutdown = lt9611_audio_shutdown,
1077 .audio_startup = lt9611_audio_startup,
1078 .get_dai_id = lt9611_hdmi_i2s_get_dai_id,
1079};
1080
1081static struct hdmi_codec_pdata codec_data = {
1082 .ops = &lt9611_codec_ops,
1083 .max_i2s_channels = 8,
1084 .i2s = 1,
1085};
1086
1087static int lt9611_audio_init(struct device *dev, struct lt9611 *lt9611)
1088{
1089 codec_data.data = lt9611;
1090 lt9611->audio_pdev =
1091 platform_device_register_data(dev, HDMI_CODEC_DRV_NAME,
1092 PLATFORM_DEVID_AUTO,
1093 &codec_data, sizeof(codec_data));
1094
1095 return PTR_ERR_OR_ZERO(lt9611->audio_pdev);
1096}
1097
1098static void lt9611_audio_exit(struct lt9611 *lt9611)
1099{
1100 if (lt9611->audio_pdev) {
1101 platform_device_unregister(lt9611->audio_pdev);
1102 lt9611->audio_pdev = NULL;
1103 }
1104}
1105
1106static int lt9611_probe(struct i2c_client *client,
1107 const struct i2c_device_id *id)
1108{
1109 struct lt9611 *lt9611;
1110 struct device *dev = &client->dev;
1111 int ret;
1112
1113 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1114 dev_err(dev, "device doesn't support I2C\n");
1115 return -ENODEV;
1116 }
1117
1118 lt9611 = devm_kzalloc(dev, sizeof(*lt9611), GFP_KERNEL);
1119 if (!lt9611)
1120 return -ENOMEM;
1121
1122 lt9611->dev = &client->dev;
1123 lt9611->client = client;
1124 lt9611->sleep = false;
1125
1126 lt9611->regmap = devm_regmap_init_i2c(client, &lt9611_regmap_config);
1127 if (IS_ERR(lt9611->regmap)) {
1128 dev_err(lt9611->dev, "regmap i2c init failed\n");
1129 return PTR_ERR(lt9611->regmap);
1130 }
1131
1132 ret = lt9611_parse_dt(&client->dev, lt9611);
1133 if (ret) {
1134 dev_err(dev, "failed to parse device tree\n");
1135 return ret;
1136 }
1137
1138 ret = lt9611_gpio_init(lt9611);
1139 if (ret < 0)
1140 goto err_of_put;
1141
1142 ret = lt9611_regulator_init(lt9611);
1143 if (ret < 0)
1144 goto err_of_put;
1145
1146 lt9611_assert_5v(lt9611);
1147
1148 ret = lt9611_regulator_enable(lt9611);
1149 if (ret)
1150 goto err_of_put;
1151
1152 lt9611_reset(lt9611);
1153
1154 ret = lt9611_read_device_rev(lt9611);
1155 if (ret) {
1156 dev_err(dev, "failed to read chip rev\n");
1157 goto err_disable_regulators;
1158 }
1159
1160 ret = devm_request_threaded_irq(dev, client->irq, NULL,
1161 lt9611_irq_thread_handler,
1162 IRQF_ONESHOT, "lt9611", lt9611);
1163 if (ret) {
1164 dev_err(dev, "failed to request irq\n");
1165 goto err_disable_regulators;
1166 }
1167
1168 i2c_set_clientdata(client, lt9611);
1169
1170 lt9611->bridge.funcs = &lt9611_bridge_funcs;
1171 lt9611->bridge.of_node = client->dev.of_node;
1172 lt9611->bridge.ops = DRM_BRIDGE_OP_DETECT | DRM_BRIDGE_OP_EDID |
1173 DRM_BRIDGE_OP_HPD | DRM_BRIDGE_OP_MODES;
1174 lt9611->bridge.type = DRM_MODE_CONNECTOR_HDMIA;
1175
1176 drm_bridge_add(&lt9611->bridge);
1177
1178 lt9611_enable_hpd_interrupts(lt9611);
1179
1180 return lt9611_audio_init(dev, lt9611);
1181
1182err_disable_regulators:
1183 regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
1184
1185err_of_put:
1186 of_node_put(lt9611->dsi1_node);
1187 of_node_put(lt9611->dsi0_node);
1188
1189 return ret;
1190}
1191
1192static int lt9611_remove(struct i2c_client *client)
1193{
1194 struct lt9611 *lt9611 = i2c_get_clientdata(client);
1195
1196 disable_irq(client->irq);
1197 lt9611_audio_exit(lt9611);
1198 drm_bridge_remove(&lt9611->bridge);
1199
1200 regulator_bulk_disable(ARRAY_SIZE(lt9611->supplies), lt9611->supplies);
1201
1202 of_node_put(lt9611->dsi1_node);
1203 of_node_put(lt9611->dsi0_node);
1204
1205 return 0;
1206}
1207
1208static struct i2c_device_id lt9611_id[] = {
1209 { "lontium,lt9611", 0 },
1210 {}
1211};
1212
1213static const struct of_device_id lt9611_match_table[] = {
1214 { .compatible = "lontium,lt9611" },
1215 { }
1216};
1217MODULE_DEVICE_TABLE(of, lt9611_match_table);
1218
1219static struct i2c_driver lt9611_driver = {
1220 .driver = {
1221 .name = "lt9611",
1222 .of_match_table = lt9611_match_table,
1223 },
1224 .probe = lt9611_probe,
1225 .remove = lt9611_remove,
1226 .id_table = lt9611_id,
1227};
1228module_i2c_driver(lt9611_driver);
1229
1230MODULE_LICENSE("GPL v2");
drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c+64−45
@@ -61,7 +61,6 @@ struct ge_b850v3_lvds { · 60 unmodified lines
61 struct drm_bridge bridge;61 struct drm_bridge bridge;
62 struct i2c_client *stdp4028_i2c;62 struct i2c_client *stdp4028_i2c;
63 struct i2c_client *stdp2690_i2c;63 struct i2c_client *stdp2690_i2c;
64 struct edid *edid;
65};64};
66 65
67static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;66static struct ge_b850v3_lvds *ge_b850v3_lvds_ptr;
@@ -131,22 +130,26 @@ err: · 63 unmodified lines
131 return NULL;130 return NULL;
132}131}
133 132
134static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)133static struct edid *ge_b850v3_lvds_get_edid(struct drm_bridge *bridge,
134 struct drm_connector *connector)
135{135{
136 struct i2c_client *client;136 struct i2c_client *client;
137 int num_modes = 0;
138 137
139 client = ge_b850v3_lvds_ptr->stdp2690_i2c;138 client = ge_b850v3_lvds_ptr->stdp2690_i2c;
140 139
141 kfree(ge_b850v3_lvds_ptr->edid);140 return (struct edid *)stdp2690_get_edid(client);
142 ge_b850v3_lvds_ptr->edid = (struct edid *)stdp2690_get_edid(client);141}
143 142
144 if (ge_b850v3_lvds_ptr->edid) {143static int ge_b850v3_lvds_get_modes(struct drm_connector *connector)
145 drm_connector_update_edid_property(connector,144{
146 ge_b850v3_lvds_ptr->edid);145 struct edid *edid;
147 num_modes = drm_add_edid_modes(connector,146 int num_modes;
148 ge_b850v3_lvds_ptr->edid);147
149 }148 edid = ge_b850v3_lvds_get_edid(&ge_b850v3_lvds_ptr->bridge, connector);
149
150 drm_connector_update_edid_property(connector, edid);
151 num_modes = drm_add_edid_modes(connector, edid);
152 kfree(edid);
150 153
151 return num_modes;154 return num_modes;
152}155}
@@ -163,8 +166,7 @@ drm_connector_helper_funcs ge_b850v3_lvds_connector_helper_funcs = { · 10 unmodified lines
163 .mode_valid = ge_b850v3_lvds_mode_valid,166 .mode_valid = ge_b850v3_lvds_mode_valid,
164};167};
165 168
166static enum drm_connector_status ge_b850v3_lvds_detect(169static enum drm_connector_status ge_b850v3_lvds_bridge_detect(struct drm_bridge *bridge)
167 struct drm_connector *connector, bool force)
168{170{
169 struct i2c_client *stdp4028_i2c =171 struct i2c_client *stdp4028_i2c =
170 ge_b850v3_lvds_ptr->stdp4028_i2c;172 ge_b850v3_lvds_ptr->stdp4028_i2c;
@@ -182,6 +184,12 @@ static enum drm_connector_status ge_b850v3_lvds_detect( · 11 unmodified lines
182 return connector_status_unknown;184 return connector_status_unknown;
183}185}
184 186
187static enum drm_connector_status ge_b850v3_lvds_detect(struct drm_connector *connector,
188 bool force)
189{
190 return ge_b850v3_lvds_bridge_detect(&ge_b850v3_lvds_ptr->bridge);
191}
192
185static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {193static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = {
186 .fill_modes = drm_helper_probe_single_connector_modes,194 .fill_modes = drm_helper_probe_single_connector_modes,
187 .detect = ge_b850v3_lvds_detect,195 .detect = ge_b850v3_lvds_detect,
@@ -191,34 +199,11 @@ static const struct drm_connector_funcs ge_b850v3_lvds_connector_funcs = { · 3 unmodified lines
191 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,199 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
192};200};
193 201
194static irqreturn_t ge_b850v3_lvds_irq_handler(int irq, void *dev_id)202static int ge_b850v3_lvds_create_connector(struct drm_bridge *bridge)
195{
196 struct i2c_client *stdp4028_i2c
197 = ge_b850v3_lvds_ptr->stdp4028_i2c;
198
199 i2c_smbus_write_word_data(stdp4028_i2c,
200 STDP4028_DPTX_IRQ_STS_REG,
201 STDP4028_DPTX_IRQ_CLEAR);
202
203 if (ge_b850v3_lvds_ptr->connector.dev)
204 drm_kms_helper_hotplug_event(ge_b850v3_lvds_ptr->connector.dev);
205
206 return IRQ_HANDLED;
207}
208
209static int ge_b850v3_lvds_attach(struct drm_bridge *bridge,
210 enum drm_bridge_attach_flags flags)
211{203{
212 struct drm_connector *connector = &ge_b850v3_lvds_ptr->connector;204 struct drm_connector *connector = &ge_b850v3_lvds_ptr->connector;
213 struct i2c_client *stdp4028_i2c
214 = ge_b850v3_lvds_ptr->stdp4028_i2c;
215 int ret;205 int ret;
216 206
217 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
218 DRM_ERROR("Fix bridge driver to make connector optional!");
219 return -EINVAL;
220 }
221
222 if (!bridge->encoder) {207 if (!bridge->encoder) {
223 DRM_ERROR("Parent encoder object not found");208 DRM_ERROR("Parent encoder object not found");
224 return -ENODEV;209 return -ENODEV;
@@ -237,9 +222,29 @@ static int ge_b850v3_lvds_attach(struct drm_bridge *bridge, · 12 unmodified lines
237 return ret;222 return ret;
238 }223 }
239 224
240 ret = drm_connector_attach_encoder(connector, bridge->encoder);225 return drm_connector_attach_encoder(connector, bridge->encoder);
241 if (ret)226}
242 return ret;227
228static irqreturn_t ge_b850v3_lvds_irq_handler(int irq, void *dev_id)
229{
230 struct i2c_client *stdp4028_i2c
231 = ge_b850v3_lvds_ptr->stdp4028_i2c;
232
233 i2c_smbus_write_word_data(stdp4028_i2c,
234 STDP4028_DPTX_IRQ_STS_REG,
235 STDP4028_DPTX_IRQ_CLEAR);
236
237 if (ge_b850v3_lvds_ptr->bridge.dev)
238 drm_kms_helper_hotplug_event(ge_b850v3_lvds_ptr->bridge.dev);
239
240 return IRQ_HANDLED;
241}
242
243static int ge_b850v3_lvds_attach(struct drm_bridge *bridge,
244 enum drm_bridge_attach_flags flags)
245{
246 struct i2c_client *stdp4028_i2c
247 = ge_b850v3_lvds_ptr->stdp4028_i2c;
243 248
244 /* Configures the bridge to re-enable interrupts after each ack. */249 /* Configures the bridge to re-enable interrupts after each ack. */
245 i2c_smbus_write_word_data(stdp4028_i2c,250 i2c_smbus_write_word_data(stdp4028_i2c,
@@ -251,11 +256,16 @@ static int ge_b850v3_lvds_attach(struct drm_bridge *bridge, · 5 unmodified lines
251 STDP4028_DPTX_IRQ_EN_REG,256 STDP4028_DPTX_IRQ_EN_REG,
252 STDP4028_DPTX_IRQ_CONFIG);257 STDP4028_DPTX_IRQ_CONFIG);
253 258
254 return 0;259 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
260 return 0;
261
262 return ge_b850v3_lvds_create_connector(bridge);
255}263}
256 264
257static const struct drm_bridge_funcs ge_b850v3_lvds_funcs = {265static const struct drm_bridge_funcs ge_b850v3_lvds_funcs = {
258 .attach = ge_b850v3_lvds_attach,266 .attach = ge_b850v3_lvds_attach,
267 .detect = ge_b850v3_lvds_bridge_detect,
268 .get_edid = ge_b850v3_lvds_get_edid,
259};269};
260 270
261static int ge_b850v3_lvds_init(struct device *dev)271static int ge_b850v3_lvds_init(struct device *dev)
@@ -291,8 +301,6 @@ static void ge_b850v3_lvds_remove(void) · 29 unmodified lines
291 301
292 drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);302 drm_bridge_remove(&ge_b850v3_lvds_ptr->bridge);
293 303
294 kfree(ge_b850v3_lvds_ptr->edid);
295
296 ge_b850v3_lvds_ptr = NULL;304 ge_b850v3_lvds_ptr = NULL;
297out:305out:
298 mutex_unlock(&ge_b850v3_lvds_dev_mutex);306 mutex_unlock(&ge_b850v3_lvds_dev_mutex);
@@ -302,14 +310,21 @@ static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, · 3 unmodified lines
302 const struct i2c_device_id *id)310 const struct i2c_device_id *id)
303{311{
304 struct device *dev = &stdp4028_i2c->dev;312 struct device *dev = &stdp4028_i2c->dev;
313 int ret;
314
315 ret = ge_b850v3_lvds_init(dev);
305 316
306 ge_b850v3_lvds_init(dev);317 if (ret)
318 return ret;
307 319
308 ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;320 ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c;
309 i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr);321 i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr);
310 322
311 /* drm bridge initialization */323 /* drm bridge initialization */
312 ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs;324 ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs;
325 ge_b850v3_lvds_ptr->bridge.ops = DRM_BRIDGE_OP_DETECT |
326 DRM_BRIDGE_OP_EDID;
327 ge_b850v3_lvds_ptr->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
313 ge_b850v3_lvds_ptr->bridge.of_node = dev->of_node;328 ge_b850v3_lvds_ptr->bridge.of_node = dev->of_node;
314 drm_bridge_add(&ge_b850v3_lvds_ptr->bridge);329 drm_bridge_add(&ge_b850v3_lvds_ptr->bridge);
315 330
@@ -361,8 +376,12 @@ static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c, · 45 unmodified lines
361 const struct i2c_device_id *id)376 const struct i2c_device_id *id)
362{377{
363 struct device *dev = &stdp2690_i2c->dev;378 struct device *dev = &stdp2690_i2c->dev;
379 int ret;
380
381 ret = ge_b850v3_lvds_init(dev);
364 382
365 ge_b850v3_lvds_init(dev);383 if (ret)
384 return ret;
366 385
367 ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c;386 ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c;
368 i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr);387 i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr);
drivers/gpu/drm/bridge/nxp-ptn3460.c+43−58
@@ -29,8 +29,7 @@ struct ptn3460_bridge { · 28 unmodified lines
29 struct drm_connector connector;29 struct drm_connector connector;
30 struct i2c_client *client;30 struct i2c_client *client;
31 struct drm_bridge bridge;31 struct drm_bridge bridge;
32 struct edid *edid;32 struct drm_bridge *panel_bridge;
33 struct drm_panel *panel;
34 struct gpio_desc *gpio_pd_n;33 struct gpio_desc *gpio_pd_n;
35 struct gpio_desc *gpio_rst_n;34 struct gpio_desc *gpio_rst_n;
36 u32 edid_emulation;35 u32 edid_emulation;
@@ -127,11 +126,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge) · 90 unmodified lines
127 usleep_range(10, 20);126 usleep_range(10, 20);
128 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);127 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
129 128
130 if (drm_panel_prepare(ptn_bridge->panel)) {
131 DRM_ERROR("failed to prepare panel\n");
132 return;
133 }
134
135 /*129 /*
136 * There's a bug in the PTN chip where it falsely asserts hotplug before130 * There's a bug in the PTN chip where it falsely asserts hotplug before
137 * it is fully functional. We're forced to wait for the maximum start up131 * it is fully functional. We're forced to wait for the maximum start up
@@ -146,16 +140,6 @@ static void ptn3460_pre_enable(struct drm_bridge *bridge) · 8 unmodified lines
146 ptn_bridge->enabled = true;140 ptn_bridge->enabled = true;
147}141}
148 142
149static void ptn3460_enable(struct drm_bridge *bridge)
150{
151 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
152
153 if (drm_panel_enable(ptn_bridge->panel)) {
154 DRM_ERROR("failed to enable panel\n");
155 return;
156 }
157}
158
159static void ptn3460_disable(struct drm_bridge *bridge)143static void ptn3460_disable(struct drm_bridge *bridge)
160{144{
161 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);145 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
@@ -165,36 +149,18 @@ static void ptn3460_disable(struct drm_bridge *bridge) · 3 unmodified lines
165 149
166 ptn_bridge->enabled = false;150 ptn_bridge->enabled = false;
167 151
168 if (drm_panel_disable(ptn_bridge->panel)) {
169 DRM_ERROR("failed to disable panel\n");
170 return;
171 }
172
173 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);152 gpiod_set_value(ptn_bridge->gpio_rst_n, 1);
174 gpiod_set_value(ptn_bridge->gpio_pd_n, 0);153 gpiod_set_value(ptn_bridge->gpio_pd_n, 0);
175}154}
176 155
177static void ptn3460_post_disable(struct drm_bridge *bridge)
178{
179 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
180 156
181 if (drm_panel_unprepare(ptn_bridge->panel)) {157static struct edid *ptn3460_get_edid(struct drm_bridge *bridge,
182 DRM_ERROR("failed to unprepare panel\n");158 struct drm_connector *connector)
183 return;
184 }
185}
186
187static int ptn3460_get_modes(struct drm_connector *connector)
188{159{
189 struct ptn3460_bridge *ptn_bridge;160 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
190 u8 *edid;
191 int ret, num_modes = 0;
192 bool power_off;161 bool power_off;
193 162 u8 *edid;
194 ptn_bridge = connector_to_ptn3460(connector);163 int ret;
195
196 if (ptn_bridge->edid)
197 return drm_add_edid_modes(connector, ptn_bridge->edid);
198 164
199 power_off = !ptn_bridge->enabled;165 power_off = !ptn_bridge->enabled;
200 ptn3460_pre_enable(&ptn_bridge->bridge);166 ptn3460_pre_enable(&ptn_bridge->bridge);
@@ -202,30 +168,40 @@ static int ptn3460_get_modes(struct drm_connector *connector) · 1 unmodified line
202 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);168 edid = kmalloc(EDID_LENGTH, GFP_KERNEL);
203 if (!edid) {169 if (!edid) {
204 DRM_ERROR("Failed to allocate EDID\n");170 DRM_ERROR("Failed to allocate EDID\n");
205 return 0;171 goto out;
206 }172 }
207 173
208 ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid,174 ret = ptn3460_read_bytes(ptn_bridge, PTN3460_EDID_ADDR, edid,
209 EDID_LENGTH);175 EDID_LENGTH);
210 if (ret) {176 if (ret) {
211 kfree(edid);177 kfree(edid);
178 edid = NULL;
212 goto out;179 goto out;
213 }180 }
214 181
215 ptn_bridge->edid = (struct edid *)edid;
216 drm_connector_update_edid_property(connector, ptn_bridge->edid);
217
218 num_modes = drm_add_edid_modes(connector, ptn_bridge->edid);
219
220out:182out:
221 if (power_off)183 if (power_off)
222 ptn3460_disable(&ptn_bridge->bridge);184 ptn3460_disable(&ptn_bridge->bridge);
223 185
186 return (struct edid *)edid;
187}
188
189static int ptn3460_connector_get_modes(struct drm_connector *connector)
190{
191 struct ptn3460_bridge *ptn_bridge = connector_to_ptn3460(connector);
192 struct edid *edid;
193 int num_modes;
194
195 edid = ptn3460_get_edid(&ptn_bridge->bridge, connector);
196 drm_connector_update_edid_property(connector, edid);
197 num_modes = drm_add_edid_modes(connector, edid);
198 kfree(edid);
199
224 return num_modes;200 return num_modes;
225}201}
226 202
227static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {203static const struct drm_connector_helper_funcs ptn3460_connector_helper_funcs = {
228 .get_modes = ptn3460_get_modes,204 .get_modes = ptn3460_connector_get_modes,
229};205};
230 206
231static const struct drm_connector_funcs ptn3460_connector_funcs = {207static const struct drm_connector_funcs ptn3460_connector_funcs = {
@@ -242,10 +218,14 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge, · 10 unmodified lines
242 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);218 struct ptn3460_bridge *ptn_bridge = bridge_to_ptn3460(bridge);
243 int ret;219 int ret;
244 220
245 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {221 /* Let this driver create connector if requested */
246 DRM_ERROR("Fix bridge driver to make connector optional!");222 ret = drm_bridge_attach(bridge->encoder, ptn_bridge->panel_bridge,
247 return -EINVAL;223 bridge, flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);
248 }224 if (ret < 0)
225 return ret;
226
227 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
228 return 0;
249 229
250 if (!bridge->encoder) {230 if (!bridge->encoder) {
251 DRM_ERROR("Parent encoder object not found");231 DRM_ERROR("Parent encoder object not found");
@@ -265,9 +245,6 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge, · 13 unmodified lines
265 drm_connector_attach_encoder(&ptn_bridge->connector,245 drm_connector_attach_encoder(&ptn_bridge->connector,
266 bridge->encoder);246 bridge->encoder);
267 247
268 if (ptn_bridge->panel)
269 drm_panel_attach(ptn_bridge->panel, &ptn_bridge->connector);
270
271 drm_helper_hpd_irq_event(ptn_bridge->connector.dev);248 drm_helper_hpd_irq_event(ptn_bridge->connector.dev);
272 249
273 return ret;250 return ret;
@@ -275,10 +252,9 @@ static int ptn3460_bridge_attach(struct drm_bridge *bridge, · 1 unmodified line
275 252
276static const struct drm_bridge_funcs ptn3460_bridge_funcs = {253static const struct drm_bridge_funcs ptn3460_bridge_funcs = {
277 .pre_enable = ptn3460_pre_enable,254 .pre_enable = ptn3460_pre_enable,
278 .enable = ptn3460_enable,
279 .disable = ptn3460_disable,255 .disable = ptn3460_disable,
280 .post_disable = ptn3460_post_disable,
281 .attach = ptn3460_bridge_attach,256 .attach = ptn3460_bridge_attach,
257 .get_edid = ptn3460_get_edid,
282};258};
283 259
284static int ptn3460_probe(struct i2c_client *client,260static int ptn3460_probe(struct i2c_client *client,
@@ -286,6 +262,8 @@ static int ptn3460_probe(struct i2c_client *client, · 1 unmodified line
286{262{
287 struct device *dev = &client->dev;263 struct device *dev = &client->dev;
288 struct ptn3460_bridge *ptn_bridge;264 struct ptn3460_bridge *ptn_bridge;
265 struct drm_bridge *panel_bridge;
266 struct drm_panel *panel;
289 int ret;267 int ret;
290 268
291 ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);269 ptn_bridge = devm_kzalloc(dev, sizeof(*ptn_bridge), GFP_KERNEL);
@@ -293,10 +271,15 @@ static int ptn3460_probe(struct i2c_client *client, · 1 unmodified line
293 return -ENOMEM;271 return -ENOMEM;
294 }272 }
295 273
296 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &ptn_bridge->panel, NULL);274 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, NULL);
297 if (ret)275 if (ret)
298 return ret;276 return ret;
299 277
278 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
279 if (IS_ERR(panel_bridge))
280 return PTR_ERR(panel_bridge);
281
282 ptn_bridge->panel_bridge = panel_bridge;
300 ptn_bridge->client = client;283 ptn_bridge->client = client;
301 284
302 ptn_bridge->gpio_pd_n = devm_gpiod_get(&client->dev, "powerdown",285 ptn_bridge->gpio_pd_n = devm_gpiod_get(&client->dev, "powerdown",
@@ -327,6 +310,8 @@ static int ptn3460_probe(struct i2c_client *client, · 24 unmodified lines
327 }310 }
328 311
329 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;312 ptn_bridge->bridge.funcs = &ptn3460_bridge_funcs;
313 ptn_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
314 ptn_bridge->bridge.type = DRM_MODE_CONNECTOR_LVDS;
330 ptn_bridge->bridge.of_node = dev->of_node;315 ptn_bridge->bridge.of_node = dev->of_node;
331 drm_bridge_add(&ptn_bridge->bridge);316 drm_bridge_add(&ptn_bridge->bridge);
332 317
drivers/gpu/drm/bridge/panel.c+0−7
@@ -82,18 +82,11 @@ static int panel_bridge_attach(struct drm_bridge *bridge, · 81 unmodified lines
82 drm_connector_attach_encoder(&panel_bridge->connector,82 drm_connector_attach_encoder(&panel_bridge->connector,
83 bridge->encoder);83 bridge->encoder);
84 84
85 ret = drm_panel_attach(panel_bridge->panel, &panel_bridge->connector);
86 if (ret < 0)
87 return ret;
88
89 return 0;85 return 0;
90}86}
91 87
92static void panel_bridge_detach(struct drm_bridge *bridge)88static void panel_bridge_detach(struct drm_bridge *bridge)
93{89{
94 struct panel_bridge *panel_bridge = drm_bridge_to_panel_bridge(bridge);
95
96 drm_panel_detach(panel_bridge->panel);
97}90}
98 91
99static void panel_bridge_pre_enable(struct drm_bridge *bridge)92static void panel_bridge_pre_enable(struct drm_bridge *bridge)
drivers/gpu/drm/bridge/parade-ps8622.c+13−87
@@ -42,10 +42,9 @@ · 41 unmodified lines
42#endif42#endif
43 43
44struct ps8622_bridge {44struct ps8622_bridge {
45 struct drm_connector connector;
46 struct i2c_client *client;45 struct i2c_client *client;
47 struct drm_bridge bridge;46 struct drm_bridge bridge;
48 struct drm_panel *panel;47 struct drm_bridge *panel_bridge;
49 struct regulator *v12;48 struct regulator *v12;
50 struct backlight_device *bl;49 struct backlight_device *bl;
51 50
@@ -64,12 +63,6 @@ static inline struct ps8622_bridge * · 12 unmodified lines
64 return container_of(bridge, struct ps8622_bridge, bridge);63 return container_of(bridge, struct ps8622_bridge, bridge);
65}64}
66 65
67static inline struct ps8622_bridge *
68 connector_to_ps8622(struct drm_connector *connector)
69{
70 return container_of(connector, struct ps8622_bridge, connector);
71}
72
73static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)66static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)
74{67{
75 int ret;68 int ret;
@@ -365,11 +358,6 @@ static void ps8622_pre_enable(struct drm_bridge *bridge) · 289 unmodified lines
365 DRM_ERROR("fails to enable ps8622->v12");358 DRM_ERROR("fails to enable ps8622->v12");
366 }359 }
367 360
368 if (drm_panel_prepare(ps8622->panel)) {
369 DRM_ERROR("failed to prepare panel\n");
370 return;
371 }
372
373 gpiod_set_value(ps8622->gpio_slp, 1);361 gpiod_set_value(ps8622->gpio_slp, 1);
374 362
375 /*363 /*
@@ -399,24 +387,9 @@ static void ps8622_pre_enable(struct drm_bridge *bridge) · 23 unmodified lines
399 ps8622->enabled = true;387 ps8622->enabled = true;
400}388}
401 389
402static void ps8622_enable(struct drm_bridge *bridge)
403{
404 struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);
405
406 if (drm_panel_enable(ps8622->panel)) {
407 DRM_ERROR("failed to enable panel\n");
408 return;
409 }
410}
411
412static void ps8622_disable(struct drm_bridge *bridge)390static void ps8622_disable(struct drm_bridge *bridge)
413{391{
414 struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);392 /* Delay after panel is disabled */
415
416 if (drm_panel_disable(ps8622->panel)) {
417 DRM_ERROR("failed to disable panel\n");
418 return;
419 }
420 msleep(PS8622_PWMO_END_T12_MS);393 msleep(PS8622_PWMO_END_T12_MS);
421}394}
422 395
@@ -436,11 +409,6 @@ static void ps8622_post_disable(struct drm_bridge *bridge) · 13 unmodified lines
436 */409 */
437 gpiod_set_value(ps8622->gpio_slp, 0);410 gpiod_set_value(ps8622->gpio_slp, 0);
438 411
439 if (drm_panel_unprepare(ps8622->panel)) {
440 DRM_ERROR("failed to unprepare panel\n");
441 return;
442 }
443
444 if (ps8622->v12)412 if (ps8622->v12)
445 regulator_disable(ps8622->v12);413 regulator_disable(ps8622->v12);
446 414
@@ -455,67 +423,17 @@ static void ps8622_post_disable(struct drm_bridge *bridge) · 8 unmodified lines
455 msleep(PS8622_POWER_OFF_T17_MS);423 msleep(PS8622_POWER_OFF_T17_MS);
456}424}
457 425
458static int ps8622_get_modes(struct drm_connector *connector)
459{
460 struct ps8622_bridge *ps8622;
461
462 ps8622 = connector_to_ps8622(connector);
463
464 return drm_panel_get_modes(ps8622->panel, connector);
465}
466
467static const struct drm_connector_helper_funcs ps8622_connector_helper_funcs = {
468 .get_modes = ps8622_get_modes,
469};
470
471static const struct drm_connector_funcs ps8622_connector_funcs = {
472 .fill_modes = drm_helper_probe_single_connector_modes,
473 .destroy = drm_connector_cleanup,
474 .reset = drm_atomic_helper_connector_reset,
475 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
476 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
477};
478
479static int ps8622_attach(struct drm_bridge *bridge,426static int ps8622_attach(struct drm_bridge *bridge,
480 enum drm_bridge_attach_flags flags)427 enum drm_bridge_attach_flags flags)
481{428{
482 struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);429 struct ps8622_bridge *ps8622 = bridge_to_ps8622(bridge);
483 int ret;
484
485 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
486 DRM_ERROR("Fix bridge driver to make connector optional!");
487 return -EINVAL;
488 }
489 430
490 if (!bridge->encoder) {431 return drm_bridge_attach(ps8622->bridge.encoder, ps8622->panel_bridge,
491 DRM_ERROR("Parent encoder object not found");432 &ps8622->bridge, flags);
492 return -ENODEV;
493 }
494
495 ps8622->connector.polled = DRM_CONNECTOR_POLL_HPD;
496 ret = drm_connector_init(bridge->dev, &ps8622->connector,
497 &ps8622_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
498 if (ret) {
499 DRM_ERROR("Failed to initialize connector with drm\n");
500 return ret;
501 }
502 drm_connector_helper_add(&ps8622->connector,
503 &ps8622_connector_helper_funcs);
504 drm_connector_register(&ps8622->connector);
505 drm_connector_attach_encoder(&ps8622->connector,
506 bridge->encoder);
507
508 if (ps8622->panel)
509 drm_panel_attach(ps8622->panel, &ps8622->connector);
510
511 drm_helper_hpd_irq_event(ps8622->connector.dev);
512
513 return ret;
514}433}
515 434
516static const struct drm_bridge_funcs ps8622_bridge_funcs = {435static const struct drm_bridge_funcs ps8622_bridge_funcs = {
517 .pre_enable = ps8622_pre_enable,436 .pre_enable = ps8622_pre_enable,
518 .enable = ps8622_enable,
519 .disable = ps8622_disable,437 .disable = ps8622_disable,
520 .post_disable = ps8622_post_disable,438 .post_disable = ps8622_post_disable,
521 .attach = ps8622_attach,439 .attach = ps8622_attach,
@@ -533,16 +451,23 @@ static int ps8622_probe(struct i2c_client *client, · 11 unmodified lines
533{451{
534 struct device *dev = &client->dev;452 struct device *dev = &client->dev;
535 struct ps8622_bridge *ps8622;453 struct ps8622_bridge *ps8622;
454 struct drm_bridge *panel_bridge;
455 struct drm_panel *panel;
536 int ret;456 int ret;
537 457
538 ps8622 = devm_kzalloc(dev, sizeof(*ps8622), GFP_KERNEL);458 ps8622 = devm_kzalloc(dev, sizeof(*ps8622), GFP_KERNEL);
539 if (!ps8622)459 if (!ps8622)
540 return -ENOMEM;460 return -ENOMEM;
541 461
542 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &ps8622->panel, NULL);462 ret = drm_of_find_panel_or_bridge(dev->of_node, 0, 0, &panel, NULL);
543 if (ret)463 if (ret)
544 return ret;464 return ret;
545 465
466 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
467 if (IS_ERR(panel_bridge))
468 return PTR_ERR(panel_bridge);
469
470 ps8622->panel_bridge = panel_bridge;
546 ps8622->client = client;471 ps8622->client = client;
547 472
548 ps8622->v12 = devm_regulator_get(dev, "vdd12");473 ps8622->v12 = devm_regulator_get(dev, "vdd12");
@@ -595,6 +520,7 @@ static int ps8622_probe(struct i2c_client *client, · 46 unmodified lines
595 }520 }
596 521
597 ps8622->bridge.funcs = &ps8622_bridge_funcs;522 ps8622->bridge.funcs = &ps8622_bridge_funcs;
523 ps8622->bridge.type = DRM_MODE_CONNECTOR_LVDS;
598 ps8622->bridge.of_node = dev->of_node;524 ps8622->bridge.of_node = dev->of_node;
599 drm_bridge_add(&ps8622->bridge);525 drm_bridge_add(&ps8622->bridge);
600 526
drivers/gpu/drm/bridge/parade-ps8640.c+22−7
@@ -82,8 +82,11 @@ static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge, · 81 unmodified lines
82 ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD,82 ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD,
83 sizeof(vdo_ctrl_buf),83 sizeof(vdo_ctrl_buf),
84 vdo_ctrl_buf);84 vdo_ctrl_buf);
85 if (ret < 0)85 if (ret < 0) {
86 DRM_ERROR("failed to %sable VDO: %d\n",
87 ctrl == ENABLE ? "en" : "dis", ret);
86 return ret;88 return ret;
89 }
87 90
88 return 0;91 return 0;
89}92}
@@ -150,10 +153,8 @@ static void ps8640_pre_enable(struct drm_bridge *bridge) · 60 unmodified lines
150 }153 }
151 154
152 ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);155 ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
153 if (ret) {156 if (ret)
154 DRM_ERROR("failed to enable VDO: %d\n", ret);
155 goto err_regulators_disable;157 goto err_regulators_disable;
156 }
157 158
158 /* Switch access edp panel's edid through i2c */159 /* Switch access edp panel's edid through i2c */
159 ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS,160 ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS,
@@ -175,9 +176,7 @@ static void ps8640_post_disable(struct drm_bridge *bridge) · 15 unmodified lines
175 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);176 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
176 int ret;177 int ret;
177 178
178 ret = ps8640_bridge_vdo_control(ps_bridge, DISABLE);179 ps8640_bridge_vdo_control(ps_bridge, DISABLE);
179 if (ret < 0)
180 DRM_ERROR("failed to disable VDO: %d\n", ret);
181 180
182 gpiod_set_value(ps_bridge->gpio_reset, 1);181 gpiod_set_value(ps_bridge->gpio_reset, 1);
183 gpiod_set_value(ps_bridge->gpio_powerdown, 1);182 gpiod_set_value(ps_bridge->gpio_powerdown, 1);
@@ -200,6 +199,10 @@ static int ps8640_bridge_attach(struct drm_bridge *bridge, · 16 unmodified lines
200 .channel = 0,199 .channel = 0,
201 .node = NULL,200 .node = NULL,
202 };201 };
202
203 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
204 return -EINVAL;
205
203 /* port@0 is ps8640 dsi input port */206 /* port@0 is ps8640 dsi input port */
204 in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);207 in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
205 if (!in_ep)208 if (!in_ep)
@@ -242,8 +245,18 @@ err_dsi_attach: · 36 unmodified lines
242 return ret;245 return ret;
243}246}
244 247
248static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
249 struct drm_connector *connector)
250{
251 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
252
253 return drm_get_edid(connector,
254 ps_bridge->page[PAGE0_DP_CNTL]->adapter);
255}
256
245static const struct drm_bridge_funcs ps8640_bridge_funcs = {257static const struct drm_bridge_funcs ps8640_bridge_funcs = {
246 .attach = ps8640_bridge_attach,258 .attach = ps8640_bridge_attach,
259 .get_edid = ps8640_bridge_get_edid,
247 .post_disable = ps8640_post_disable,260 .post_disable = ps8640_post_disable,
248 .pre_enable = ps8640_pre_enable,261 .pre_enable = ps8640_pre_enable,
249};262};
@@ -294,6 +307,8 @@ static int ps8640_probe(struct i2c_client *client) · 44 unmodified lines
294 307
295 ps_bridge->bridge.funcs = &ps8640_bridge_funcs;308 ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
296 ps_bridge->bridge.of_node = dev->of_node;309 ps_bridge->bridge.of_node = dev->of_node;
310 ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
311 ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
297 312
298 ps_bridge->page[PAGE0_DP_CNTL] = client;313 ps_bridge->page[PAGE0_DP_CNTL] = client;
299 314
drivers/gpu/drm/bridge/tc358762.c+280−0
@@ -0,0 +1,280 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2020 Marek Vasut <marex@denx.de>
4 *
5 * Based on tc358764.c by
6 * Andrzej Hajda <a.hajda@samsung.com>
7 * Maciej Purski <m.purski@samsung.com>
8 *
9 * Based on rpi_touchscreen.c by
10 * Eric Anholt <eric@anholt.net>
11 */
12
13#include <linux/delay.h>
14#include <linux/module.h>
15#include <linux/of_graph.h>
16#include <linux/regulator/consumer.h>
17
18#include <video/mipi_display.h>
19
20#include <drm/drm_atomic_helper.h>
21#include <drm/drm_crtc.h>
22#include <drm/drm_fb_helper.h>
23#include <drm/drm_mipi_dsi.h>
24#include <drm/drm_of.h>
25#include <drm/drm_panel.h>
26#include <drm/drm_print.h>
27#include <drm/drm_probe_helper.h>
28
29/* PPI layer registers */
30#define PPI_STARTPPI 0x0104 /* START control bit */
31#define PPI_LPTXTIMECNT 0x0114 /* LPTX timing signal */
32#define PPI_D0S_ATMR 0x0144
33#define PPI_D1S_ATMR 0x0148
34#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */
35#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */
36#define PPI_START_FUNCTION 1
37
38/* DSI layer registers */
39#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */
40#define DSI_LANEENABLE 0x0210 /* Enables each lane */
41#define DSI_RX_START 1
42
43/* LCDC/DPI Host Registers */
44#define LCDCTRL 0x0420
45
46/* SPI Master Registers */
47#define SPICMR 0x0450
48#define SPITCR 0x0454
49
50/* System Controller Registers */
51#define SYSCTRL 0x0464
52
53/* System registers */
54#define LPX_PERIOD 3
55
56/* Lane enable PPI and DSI register bits */
57#define LANEENABLE_CLEN BIT(0)
58#define LANEENABLE_L0EN BIT(1)
59#define LANEENABLE_L1EN BIT(2)
60
61struct tc358762 {
62 struct device *dev;
63 struct drm_bridge bridge;
64 struct drm_connector connector;
65 struct regulator *regulator;
66 struct drm_bridge *panel_bridge;
67 bool pre_enabled;
68 int error;
69};
70
71static int tc358762_clear_error(struct tc358762 *ctx)
72{
73 int ret = ctx->error;
74
75 ctx->error = 0;
76 return ret;
77}
78
79static void tc358762_write(struct tc358762 *ctx, u16 addr, u32 val)
80{
81 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
82 ssize_t ret;
83 u8 data[6];
84
85 if (ctx->error)
86 return;
87
88 data[0] = addr;
89 data[1] = addr >> 8;
90 data[2] = val;
91 data[3] = val >> 8;
92 data[4] = val >> 16;
93 data[5] = val >> 24;
94
95 ret = mipi_dsi_generic_write(dsi, data, sizeof(data));
96 if (ret < 0)
97 ctx->error = ret;
98}
99
100static inline struct tc358762 *bridge_to_tc358762(struct drm_bridge *bridge)
101{
102 return container_of(bridge, struct tc358762, bridge);
103}
104
105static int tc358762_init(struct tc358762 *ctx)
106{
107 tc358762_write(ctx, DSI_LANEENABLE,
108 LANEENABLE_L0EN | LANEENABLE_CLEN);
109 tc358762_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5);
110 tc358762_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5);
111 tc358762_write(ctx, PPI_D0S_ATMR, 0);
112 tc358762_write(ctx, PPI_D1S_ATMR, 0);
113 tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD);
114
115 tc358762_write(ctx, SPICMR, 0x00);
116 tc358762_write(ctx, LCDCTRL, 0x00100150);
117 tc358762_write(ctx, SYSCTRL, 0x040f);
118 msleep(100);
119
120 tc358762_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION);
121 tc358762_write(ctx, DSI_STARTDSI, DSI_RX_START);
122
123 msleep(100);
124
125 return tc358762_clear_error(ctx);
126}
127
128static void tc358762_post_disable(struct drm_bridge *bridge)
129{
130 struct tc358762 *ctx = bridge_to_tc358762(bridge);
131 int ret;
132
133 /*
134 * The post_disable hook might be called multiple times.
135 * We want to avoid regulator imbalance below.
136 */
137 if (!ctx->pre_enabled)
138 return;
139
140 ctx->pre_enabled = false;
141
142 ret = regulator_disable(ctx->regulator);
143 if (ret < 0)
144 dev_err(ctx->dev, "error disabling regulators (%d)\n", ret);
145}
146
147static void tc358762_pre_enable(struct drm_bridge *bridge)
148{
149 struct tc358762 *ctx = bridge_to_tc358762(bridge);
150 int ret;
151
152 ret = regulator_enable(ctx->regulator);
153 if (ret < 0)
154 dev_err(ctx->dev, "error enabling regulators (%d)\n", ret);
155
156 ret = tc358762_init(ctx);
157 if (ret < 0)
158 dev_err(ctx->dev, "error initializing bridge (%d)\n", ret);
159
160 ctx->pre_enabled = true;
161}
162
163static int tc358762_attach(struct drm_bridge *bridge,
164 enum drm_bridge_attach_flags flags)
165{
166 struct tc358762 *ctx = bridge_to_tc358762(bridge);
167
168 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge,
169 bridge, flags);
170}
171
172static const struct drm_bridge_funcs tc358762_bridge_funcs = {
173 .post_disable = tc358762_post_disable,
174 .pre_enable = tc358762_pre_enable,
175 .attach = tc358762_attach,
176};
177
178static int tc358762_parse_dt(struct tc358762 *ctx)
179{
180 struct drm_bridge *panel_bridge;
181 struct device *dev = ctx->dev;
182 struct drm_panel *panel;
183 int ret;
184
185 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
186 if (ret)
187 return ret;
188
189 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
190
191 if (IS_ERR(panel_bridge))
192 return PTR_ERR(panel_bridge);
193
194 ctx->panel_bridge = panel_bridge;
195
196 return 0;
197}
198
199static int tc358762_configure_regulators(struct tc358762 *ctx)
200{
201 ctx->regulator = devm_regulator_get(ctx->dev, "vddc");
202 if (IS_ERR(ctx->regulator))
203 return PTR_ERR(ctx->regulator);
204
205 return 0;
206}
207
208static int tc358762_probe(struct mipi_dsi_device *dsi)
209{
210 struct device *dev = &dsi->dev;
211 struct tc358762 *ctx;
212 int ret;
213
214 ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL);
215 if (!ctx)
216 return -ENOMEM;
217
218 mipi_dsi_set_drvdata(dsi, ctx);
219
220 ctx->dev = dev;
221 ctx->pre_enabled = false;
222
223 /* TODO: Find out how to get dual-lane mode working */
224 dsi->lanes = 1;
225 dsi->format = MIPI_DSI_FMT_RGB888;
226 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
227 MIPI_DSI_MODE_LPM;
228
229 ret = tc358762_parse_dt(ctx);
230 if (ret < 0)
231 return ret;
232
233 ret = tc358762_configure_regulators(ctx);
234 if (ret < 0)
235 return ret;
236
237 ctx->bridge.funcs = &tc358762_bridge_funcs;
238 ctx->bridge.type = DRM_MODE_CONNECTOR_DPI;
239 ctx->bridge.of_node = dev->of_node;
240
241 drm_bridge_add(&ctx->bridge);
242
243 ret = mipi_dsi_attach(dsi);
244 if (ret < 0) {
245 drm_bridge_remove(&ctx->bridge);
246 dev_err(dev, "failed to attach dsi\n");
247 }
248
249 return ret;
250}
251
252static int tc358762_remove(struct mipi_dsi_device *dsi)
253{
254 struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi);
255
256 mipi_dsi_detach(dsi);
257 drm_bridge_remove(&ctx->bridge);
258
259 return 0;
260}
261
262static const struct of_device_id tc358762_of_match[] = {
263 { .compatible = "toshiba,tc358762" },
264 { }
265};
266MODULE_DEVICE_TABLE(of, tc358762_of_match);
267
268static struct mipi_dsi_driver tc358762_driver = {
269 .probe = tc358762_probe,
270 .remove = tc358762_remove,
271 .driver = {
272 .name = "tc358762",
273 .of_match_table = tc358762_of_match,
274 },
275};
276module_mipi_dsi_driver(tc358762_driver);
277
278MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
279MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358762 DSI/DPI Bridge");
280MODULE_LICENSE("GPL v2");
drivers/gpu/drm/bridge/tc358764.c+15−94
@@ -153,10 +153,9 @@ static const char * const tc358764_supplies[] = { · 152 unmodified lines
153struct tc358764 {153struct tc358764 {
154 struct device *dev;154 struct device *dev;
155 struct drm_bridge bridge;155 struct drm_bridge bridge;
156 struct drm_connector connector;
157 struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)];156 struct regulator_bulk_data supplies[ARRAY_SIZE(tc358764_supplies)];
158 struct gpio_desc *gpio_reset;157 struct gpio_desc *gpio_reset;
159 struct drm_panel *panel;158 struct drm_bridge *panel_bridge;
160 int error;159 int error;
161};160};
162 161
@@ -210,12 +209,6 @@ static inline struct tc358764 *bridge_to_tc358764(struct drm_bridge *bridge) · 47 unmodified lines
210 return container_of(bridge, struct tc358764, bridge);209 return container_of(bridge, struct tc358764, bridge);
211}210}
212 211
213static inline
214struct tc358764 *connector_to_tc358764(struct drm_connector *connector)
215{
216 return container_of(connector, struct tc358764, connector);
217}
218
219static int tc358764_init(struct tc358764 *ctx)212static int tc358764_init(struct tc358764 *ctx)
220{213{
221 u32 v = 0;214 u32 v = 0;
@@ -278,43 +271,11 @@ static void tc358764_reset(struct tc358764 *ctx) · 56 unmodified lines
278 usleep_range(1000, 2000);271 usleep_range(1000, 2000);
279}272}
280 273
281static int tc358764_get_modes(struct drm_connector *connector)
282{
283 struct tc358764 *ctx = connector_to_tc358764(connector);
284
285 return drm_panel_get_modes(ctx->panel, connector);
286}
287
288static const
289struct drm_connector_helper_funcs tc358764_connector_helper_funcs = {
290 .get_modes = tc358764_get_modes,
291};
292
293static const struct drm_connector_funcs tc358764_connector_funcs = {
294 .fill_modes = drm_helper_probe_single_connector_modes,
295 .destroy = drm_connector_cleanup,
296 .reset = drm_atomic_helper_connector_reset,
297 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
298 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
299};
300
301static void tc358764_disable(struct drm_bridge *bridge)
302{
303 struct tc358764 *ctx = bridge_to_tc358764(bridge);
304 int ret = drm_panel_disable(bridge_to_tc358764(bridge)->panel);
305
306 if (ret < 0)
307 dev_err(ctx->dev, "error disabling panel (%d)\n", ret);
308}
309
310static void tc358764_post_disable(struct drm_bridge *bridge)274static void tc358764_post_disable(struct drm_bridge *bridge)
311{275{
312 struct tc358764 *ctx = bridge_to_tc358764(bridge);276 struct tc358764 *ctx = bridge_to_tc358764(bridge);
313 int ret;277 int ret;
314 278
315 ret = drm_panel_unprepare(ctx->panel);
316 if (ret < 0)
317 dev_err(ctx->dev, "error unpreparing panel (%d)\n", ret);
318 tc358764_reset(ctx);279 tc358764_reset(ctx);
319 usleep_range(10000, 15000);280 usleep_range(10000, 15000);
320 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);281 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
@@ -335,73 +296,28 @@ static void tc358764_pre_enable(struct drm_bridge *bridge) · 14 unmodified lines
335 ret = tc358764_init(ctx);296 ret = tc358764_init(ctx);
336 if (ret < 0)297 if (ret < 0)
337 dev_err(ctx->dev, "error initializing bridge (%d)\n", ret);298 dev_err(ctx->dev, "error initializing bridge (%d)\n", ret);
338 ret = drm_panel_prepare(ctx->panel);
339 if (ret < 0)
340 dev_err(ctx->dev, "error preparing panel (%d)\n", ret);
341}
342
343static void tc358764_enable(struct drm_bridge *bridge)
344{
345 struct tc358764 *ctx = bridge_to_tc358764(bridge);
346 int ret = drm_panel_enable(ctx->panel);
347
348 if (ret < 0)
349 dev_err(ctx->dev, "error enabling panel (%d)\n", ret);
350}299}
351 300
352static int tc358764_attach(struct drm_bridge *bridge,301static int tc358764_attach(struct drm_bridge *bridge,
353 enum drm_bridge_attach_flags flags)302 enum drm_bridge_attach_flags flags)
354{
355 struct tc358764 *ctx = bridge_to_tc358764(bridge);
356 struct drm_device *drm = bridge->dev;
357 int ret;
358
359 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
360 DRM_ERROR("Fix bridge driver to make connector optional!");
361 return -EINVAL;
362 }
363
364 ctx->connector.polled = DRM_CONNECTOR_POLL_HPD;
365 ret = drm_connector_init(drm, &ctx->connector,
366 &tc358764_connector_funcs,
367 DRM_MODE_CONNECTOR_LVDS);
368 if (ret) {
369 DRM_ERROR("Failed to initialize connector\n");
370 return ret;
371 }
372
373 drm_connector_helper_add(&ctx->connector,
374 &tc358764_connector_helper_funcs);
375 drm_connector_attach_encoder(&ctx->connector, bridge->encoder);
376 drm_panel_attach(ctx->panel, &ctx->connector);
377 ctx->connector.funcs->reset(&ctx->connector);
378 drm_connector_register(&ctx->connector);
379
380 return 0;
381}
382
383static void tc358764_detach(struct drm_bridge *bridge)
384{303{
385 struct tc358764 *ctx = bridge_to_tc358764(bridge);304 struct tc358764 *ctx = bridge_to_tc358764(bridge);
386 305
387 drm_connector_unregister(&ctx->connector);306 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge,
388 drm_panel_detach(ctx->panel);307 bridge, flags);
389 ctx->panel = NULL;
390 drm_connector_put(&ctx->connector);
391}308}
392 309
393static const struct drm_bridge_funcs tc358764_bridge_funcs = {310static const struct drm_bridge_funcs tc358764_bridge_funcs = {
394 .disable = tc358764_disable,
395 .post_disable = tc358764_post_disable,311 .post_disable = tc358764_post_disable,
396 .enable = tc358764_enable,
397 .pre_enable = tc358764_pre_enable,312 .pre_enable = tc358764_pre_enable,
398 .attach = tc358764_attach,313 .attach = tc358764_attach,
399 .detach = tc358764_detach,
400};314};
401 315
402static int tc358764_parse_dt(struct tc358764 *ctx)316static int tc358764_parse_dt(struct tc358764 *ctx)
403{317{
318 struct drm_bridge *panel_bridge;
404 struct device *dev = ctx->dev;319 struct device *dev = ctx->dev;
320 struct drm_panel *panel;
405 int ret;321 int ret;
406 322
407 ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);323 ctx->gpio_reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
@@ -410,12 +326,16 @@ static int tc358764_parse_dt(struct tc358764 *ctx) · 2 unmodified lines
410 return PTR_ERR(ctx->gpio_reset);326 return PTR_ERR(ctx->gpio_reset);
411 }327 }
412 328
413 ret = drm_of_find_panel_or_bridge(ctx->dev->of_node, 1, 0, &ctx->panel,329 ret = drm_of_find_panel_or_bridge(dev->of_node, 1, 0, &panel, NULL);
414 NULL);330 if (ret)
415 if (ret && ret != -EPROBE_DEFER)331 return ret;
416 dev_err(dev, "cannot find panel (%d)\n", ret);
417 332
418 return ret;333 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
334 if (IS_ERR(panel_bridge))
335 return PTR_ERR(panel_bridge);
336
337 ctx->panel_bridge = panel_bridge;
338 return 0;
419}339}
420 340
421static int tc358764_configure_regulators(struct tc358764 *ctx)341static int tc358764_configure_regulators(struct tc358764 *ctx)
@@ -461,6 +381,7 @@ static int tc358764_probe(struct mipi_dsi_device *dsi) · 39 unmodified lines
461 return ret;381 return ret;
462 382
463 ctx->bridge.funcs = &tc358764_bridge_funcs;383 ctx->bridge.funcs = &tc358764_bridge_funcs;
384 ctx->bridge.type = DRM_MODE_CONNECTOR_LVDS;
464 ctx->bridge.of_node = dev->of_node;385 ctx->bridge.of_node = dev->of_node;
465 386
466 drm_bridge_add(&ctx->bridge);387 drm_bridge_add(&ctx->bridge);
drivers/gpu/drm/bridge/tc358767.c+66−57
@@ -244,14 +244,12 @@ struct tc_data { · 243 unmodified lines
244 struct drm_dp_aux aux;244 struct drm_dp_aux aux;
245 245
246 struct drm_bridge bridge;246 struct drm_bridge bridge;
247 struct drm_bridge *panel_bridge;
247 struct drm_connector connector;248 struct drm_connector connector;
248 struct drm_panel *panel;
249 249
250 /* link settings */250 /* link settings */
251 struct tc_edp_link link;251 struct tc_edp_link link;
252 252
253 /* display edid */
254 struct edid *edid;
255 /* current mode */253 /* current mode */
256 struct drm_display_mode mode;254 struct drm_display_mode mode;
257 255
@@ -1236,13 +1234,6 @@ static int tc_stream_disable(struct tc_data *tc) · 978 unmodified lines
1236 return 0;1234 return 0;
1237}1235}
1238 1236
1239static void tc_bridge_pre_enable(struct drm_bridge *bridge)
1240{
1241 struct tc_data *tc = bridge_to_tc(bridge);
1242
1243 drm_panel_prepare(tc->panel);
1244}
1245
1246static void tc_bridge_enable(struct drm_bridge *bridge)1237static void tc_bridge_enable(struct drm_bridge *bridge)
1247{1238{
1248 struct tc_data *tc = bridge_to_tc(bridge);1239 struct tc_data *tc = bridge_to_tc(bridge);
@@ -1266,8 +1257,6 @@ static void tc_bridge_enable(struct drm_bridge *bridge) · 17 unmodified lines
1266 tc_main_link_disable(tc);1257 tc_main_link_disable(tc);
1267 return;1258 return;
1268 }1259 }
1269
1270 drm_panel_enable(tc->panel);
1271}1260}
1272 1261
1273static void tc_bridge_disable(struct drm_bridge *bridge)1262static void tc_bridge_disable(struct drm_bridge *bridge)
@@ -1275,8 +1264,6 @@ static void tc_bridge_disable(struct drm_bridge *bridge) · 1 unmodified line
1275 struct tc_data *tc = bridge_to_tc(bridge);1264 struct tc_data *tc = bridge_to_tc(bridge);
1276 int ret;1265 int ret;
1277 1266
1278 drm_panel_disable(tc->panel);
1279
1280 ret = tc_stream_disable(tc);1267 ret = tc_stream_disable(tc);
1281 if (ret < 0)1268 if (ret < 0)
1282 dev_err(tc->dev, "main link stream stop error: %d\n", ret);1269 dev_err(tc->dev, "main link stream stop error: %d\n", ret);
@@ -1286,13 +1273,6 @@ static void tc_bridge_disable(struct drm_bridge *bridge) · 3 unmodified lines
1286 dev_err(tc->dev, "main link disable error: %d\n", ret);1273 dev_err(tc->dev, "main link disable error: %d\n", ret);
1287}1274}
1288 1275
1289static void tc_bridge_post_disable(struct drm_bridge *bridge)
1290{
1291 struct tc_data *tc = bridge_to_tc(bridge);
1292
1293 drm_panel_unprepare(tc->panel);
1294}
1295
1296static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,1276static bool tc_bridge_mode_fixup(struct drm_bridge *bridge,
1297 const struct drm_display_mode *mode,1277 const struct drm_display_mode *mode,
1298 struct drm_display_mode *adj)1278 struct drm_display_mode *adj)
@@ -1335,11 +1315,19 @@ static void tc_bridge_mode_set(struct drm_bridge *bridge, · 36 unmodified lines
1335 tc->mode = *mode;1315 tc->mode = *mode;
1336}1316}
1337 1317
1318static struct edid *tc_get_edid(struct drm_bridge *bridge,
1319 struct drm_connector *connector)
1320{
1321 struct tc_data *tc = bridge_to_tc(bridge);
1322
1323 return drm_get_edid(connector, &tc->aux.ddc);
1324}
1325
1338static int tc_connector_get_modes(struct drm_connector *connector)1326static int tc_connector_get_modes(struct drm_connector *connector)
1339{1327{
1340 struct tc_data *tc = connector_to_tc(connector);1328 struct tc_data *tc = connector_to_tc(connector);
1329 int num_modes;
1341 struct edid *edid;1330 struct edid *edid;
1342 int count;
1343 int ret;1331 int ret;
1344 1332
1345 ret = tc_get_display_props(tc);1333 ret = tc_get_display_props(tc);
@@ -1348,42 +1336,30 @@ static int tc_connector_get_modes(struct drm_connector *connector) · 2 unmodified lines
1348 return 0;1336 return 0;
1349 }1337 }
1350 1338
1351 count = drm_panel_get_modes(tc->panel, connector);1339 if (tc->panel_bridge) {
1352 if (count > 0)1340 num_modes = drm_bridge_get_modes(tc->panel_bridge, connector);
1353 return count;1341 if (num_modes > 0)
1354 1342 return num_modes;
1355 edid = drm_get_edid(connector, &tc->aux.ddc);1343 }
1356
1357 kfree(tc->edid);
1358 tc->edid = edid;
1359 if (!edid)
1360 return 0;
1361 1344
1362 drm_connector_update_edid_property(connector, edid);1345 edid = tc_get_edid(&tc->bridge, connector);
1363 count = drm_add_edid_modes(connector, edid);1346 num_modes = drm_add_edid_modes(connector, edid);
1347 kfree(edid);
1364 1348
1365 return count;1349 return num_modes;
1366}1350}
1367 1351
1368static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {1352static const struct drm_connector_helper_funcs tc_connector_helper_funcs = {
1369 .get_modes = tc_connector_get_modes,1353 .get_modes = tc_connector_get_modes,
1370};1354};
1371 1355
1372static enum drm_connector_status tc_connector_detect(struct drm_connector *connector,1356static enum drm_connector_status tc_bridge_detect(struct drm_bridge *bridge)
1373 bool force)
1374{1357{
1375 struct tc_data *tc = connector_to_tc(connector);1358 struct tc_data *tc = bridge_to_tc(bridge);
1376 bool conn;1359 bool conn;
1377 u32 val;1360 u32 val;
1378 int ret;1361 int ret;
1379 1362
1380 if (tc->hpd_pin < 0) {
1381 if (tc->panel)
1382 return connector_status_connected;
1383 else
1384 return connector_status_unknown;
1385 }
1386
1387 ret = regmap_read(tc->regmap, GPIOI, &val);1363 ret = regmap_read(tc->regmap, GPIOI, &val);
1388 if (ret)1364 if (ret)
1389 return connector_status_unknown;1365 return connector_status_unknown;
@@ -1396,6 +1372,20 @@ static enum drm_connector_status tc_connector_detect(struct drm_connector *conne · 6 unmodified lines
1396 return connector_status_disconnected;1372 return connector_status_disconnected;
1397}1373}
1398 1374
1375static enum drm_connector_status
1376tc_connector_detect(struct drm_connector *connector, bool force)
1377{
1378 struct tc_data *tc = connector_to_tc(connector);
1379
1380 if (tc->hpd_pin >= 0)
1381 return tc_bridge_detect(&tc->bridge);
1382
1383 if (tc->panel_bridge)
1384 return connector_status_connected;
1385 else
1386 return connector_status_unknown;
1387}
1388
1399static const struct drm_connector_funcs tc_connector_funcs = {1389static const struct drm_connector_funcs tc_connector_funcs = {
1400 .detect = tc_connector_detect,1390 .detect = tc_connector_detect,
1401 .fill_modes = drm_helper_probe_single_connector_modes,1391 .fill_modes = drm_helper_probe_single_connector_modes,
@@ -1413,16 +1403,20 @@ static int tc_bridge_attach(struct drm_bridge *bridge, · 11 unmodified lines
1413 struct drm_device *drm = bridge->dev;1403 struct drm_device *drm = bridge->dev;
1414 int ret;1404 int ret;
1415 1405
1416 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {1406 if (tc->panel_bridge) {
1417 DRM_ERROR("Fix bridge driver to make connector optional!");1407 /* If a connector is required then this driver shall create it */
1418 return -EINVAL;1408 ret = drm_bridge_attach(tc->bridge.encoder, tc->panel_bridge,
1409 &tc->bridge, flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);
1410 if (ret)
1411 return ret;
1419 }1412 }
1420 1413
1414 if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
1415 return 0;
1416
1421 /* Create DP/eDP connector */1417 /* Create DP/eDP connector */
1422 drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);1418 drm_connector_helper_add(&tc->connector, &tc_connector_helper_funcs);
1423 ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs,1419 ret = drm_connector_init(drm, &tc->connector, &tc_connector_funcs, tc->bridge.type);
1424 tc->panel ? DRM_MODE_CONNECTOR_eDP :
1425 DRM_MODE_CONNECTOR_DisplayPort);
1426 if (ret)1420 if (ret)
1427 return ret;1421 return ret;
1428 1422
@@ -1435,9 +1429,6 @@ static int tc_bridge_attach(struct drm_bridge *bridge, · 6 unmodified lines
1435 DRM_CONNECTOR_POLL_DISCONNECT;1429 DRM_CONNECTOR_POLL_DISCONNECT;
1436 }1430 }
1437 1431
1438 if (tc->panel)
1439 drm_panel_attach(tc->panel, &tc->connector);
1440
1441 drm_display_info_set_bus_formats(&tc->connector.display_info,1432 drm_display_info_set_bus_formats(&tc->connector.display_info,
1442 &bus_format, 1);1433 &bus_format, 1);
1443 tc->connector.display_info.bus_flags =1434 tc->connector.display_info.bus_flags =
@@ -1453,11 +1444,11 @@ static const struct drm_bridge_funcs tc_bridge_funcs = { · 9 unmodified lines
1453 .attach = tc_bridge_attach,1444 .attach = tc_bridge_attach,
1454 .mode_valid = tc_mode_valid,1445 .mode_valid = tc_mode_valid,
1455 .mode_set = tc_bridge_mode_set,1446 .mode_set = tc_bridge_mode_set,
1456 .pre_enable = tc_bridge_pre_enable,
1457 .enable = tc_bridge_enable,1447 .enable = tc_bridge_enable,
1458 .disable = tc_bridge_disable,1448 .disable = tc_bridge_disable,
1459 .post_disable = tc_bridge_post_disable,
1460 .mode_fixup = tc_bridge_mode_fixup,1449 .mode_fixup = tc_bridge_mode_fixup,
1450 .detect = tc_bridge_detect,
1451 .get_edid = tc_get_edid,
1461};1452};
1462 1453
1463static bool tc_readable_reg(struct device *dev, unsigned int reg)1454static bool tc_readable_reg(struct device *dev, unsigned int reg)
@@ -1547,6 +1538,7 @@ static irqreturn_t tc_irq_handler(int irq, void *arg) · 83 unmodified lines
1547static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)1538static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
1548{1539{
1549 struct device *dev = &client->dev;1540 struct device *dev = &client->dev;
1541 struct drm_panel *panel;
1550 struct tc_data *tc;1542 struct tc_data *tc;
1551 int ret;1543 int ret;
1552 1544
@@ -1557,10 +1549,23 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) · 4 unmodified lines
1557 tc->dev = dev;1549 tc->dev = dev;
1558 1550
1559 /* port@2 is the output port */1551 /* port@2 is the output port */
1560 ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &tc->panel, NULL);1552 ret = drm_of_find_panel_or_bridge(dev->of_node, 2, 0, &panel, NULL);
1561 if (ret && ret != -ENODEV)1553 if (ret && ret != -ENODEV)
1562 return ret;1554 return ret;
1563 1555
1556 if (panel) {
1557 struct drm_bridge *panel_bridge;
1558
1559 panel_bridge = devm_drm_panel_bridge_add(dev, panel);
1560 if (IS_ERR(panel_bridge))
1561 return PTR_ERR(panel_bridge);
1562
1563 tc->panel_bridge = panel_bridge;
1564 tc->bridge.type = DRM_MODE_CONNECTOR_eDP;
1565 } else {
1566 tc->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
1567 }
1568
1564 /* Shut down GPIO is optional */1569 /* Shut down GPIO is optional */
1565 tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);1570 tc->sd_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
1566 if (IS_ERR(tc->sd_gpio))1571 if (IS_ERR(tc->sd_gpio))
@@ -1680,6 +1685,10 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id) · 113 unmodified lines
1680 return ret;1685 return ret;
1681 1686
1682 tc->bridge.funcs = &tc_bridge_funcs;1687 tc->bridge.funcs = &tc_bridge_funcs;
1688 if (tc->hpd_pin >= 0)
1689 tc->bridge.ops |= DRM_BRIDGE_OP_DETECT;
1690 tc->bridge.ops |= DRM_BRIDGE_OP_EDID;
1691
1683 tc->bridge.of_node = dev->of_node;1692 tc->bridge.of_node = dev->of_node;
1684 drm_bridge_add(&tc->bridge);1693 drm_bridge_add(&tc->bridge);
1685 1694
drivers/gpu/drm/bridge/tc358775.c+749−0
@@ -0,0 +1,749 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * TC358775 DSI to LVDS bridge driver
4 *
5 * Copyright (C) 2020 SMART Wireless Computing
6 * Author: Vinay Simha BN <simhavcs@gmail.com>
7 *
8 */
9/* #define DEBUG */
10#include <linux/bitfield.h>
11#include <linux/clk.h>
12#include <linux/device.h>
13#include <linux/gpio/consumer.h>
14#include <linux/i2c.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/regulator/consumer.h>
18#include <linux/slab.h>
19
20#include <asm/unaligned.h>
21
22#include <drm/drm_atomic_helper.h>
23#include <drm/drm_bridge.h>
24#include <drm/drm_crtc_helper.h>
25#include <drm/drm_dp_helper.h>
26#include <drm/drm_mipi_dsi.h>
27#include <drm/drm_of.h>
28#include <drm/drm_panel.h>
29#include <drm/drm_probe_helper.h>
30
31#define FLD_VAL(val, start, end) FIELD_PREP(GENMASK(start, end), val)
32
33/* Registers */
34
35/* DSI D-PHY Layer Registers */
36#define D0W_DPHYCONTTX 0x0004 /* Data Lane 0 DPHY Tx Control */
37#define CLW_DPHYCONTRX 0x0020 /* Clock Lane DPHY Rx Control */
38#define D0W_DPHYCONTRX 0x0024 /* Data Lane 0 DPHY Rx Control */
39#define D1W_DPHYCONTRX 0x0028 /* Data Lane 1 DPHY Rx Control */
40#define D2W_DPHYCONTRX 0x002C /* Data Lane 2 DPHY Rx Control */
41#define D3W_DPHYCONTRX 0x0030 /* Data Lane 3 DPHY Rx Control */
42#define COM_DPHYCONTRX 0x0038 /* DPHY Rx Common Control */
43#define CLW_CNTRL 0x0040 /* Clock Lane Control */
44#define D0W_CNTRL 0x0044 /* Data Lane 0 Control */
45#define D1W_CNTRL 0x0048 /* Data Lane 1 Control */
46#define D2W_CNTRL 0x004C /* Data Lane 2 Control */
47#define D3W_CNTRL 0x0050 /* Data Lane 3 Control */
48#define DFTMODE_CNTRL 0x0054 /* DFT Mode Control */
49
50/* DSI PPI Layer Registers */
51#define PPI_STARTPPI 0x0104 /* START control bit of PPI-TX function. */
52#define PPI_START_FUNCTION 1
53
54#define PPI_BUSYPPI 0x0108
55#define PPI_LINEINITCNT 0x0110 /* Line Initialization Wait Counter */
56#define PPI_LPTXTIMECNT 0x0114
57#define PPI_LANEENABLE 0x0134 /* Enables each lane at the PPI layer. */
58#define PPI_TX_RX_TA 0x013C /* DSI Bus Turn Around timing parameters */
59
60/* Analog timer function enable */
61#define PPI_CLS_ATMR 0x0140 /* Delay for Clock Lane in LPRX */
62#define PPI_D0S_ATMR 0x0144 /* Delay for Data Lane 0 in LPRX */
63#define PPI_D1S_ATMR 0x0148 /* Delay for Data Lane 1 in LPRX */
64#define PPI_D2S_ATMR 0x014C /* Delay for Data Lane 2 in LPRX */
65#define PPI_D3S_ATMR 0x0150 /* Delay for Data Lane 3 in LPRX */
66
67#define PPI_D0S_CLRSIPOCOUNT 0x0164 /* For lane 0 */
68#define PPI_D1S_CLRSIPOCOUNT 0x0168 /* For lane 1 */
69#define PPI_D2S_CLRSIPOCOUNT 0x016C /* For lane 2 */
70#define PPI_D3S_CLRSIPOCOUNT 0x0170 /* For lane 3 */
71
72#define CLS_PRE 0x0180 /* Digital Counter inside of PHY IO */
73#define D0S_PRE 0x0184 /* Digital Counter inside of PHY IO */
74#define D1S_PRE 0x0188 /* Digital Counter inside of PHY IO */
75#define D2S_PRE 0x018C /* Digital Counter inside of PHY IO */
76#define D3S_PRE 0x0190 /* Digital Counter inside of PHY IO */
77#define CLS_PREP 0x01A0 /* Digital Counter inside of PHY IO */
78#define D0S_PREP 0x01A4 /* Digital Counter inside of PHY IO */
79#define D1S_PREP 0x01A8 /* Digital Counter inside of PHY IO */
80#define D2S_PREP 0x01AC /* Digital Counter inside of PHY IO */
81#define D3S_PREP 0x01B0 /* Digital Counter inside of PHY IO */
82#define CLS_ZERO 0x01C0 /* Digital Counter inside of PHY IO */
83#define D0S_ZERO 0x01C4 /* Digital Counter inside of PHY IO */
84#define D1S_ZERO 0x01C8 /* Digital Counter inside of PHY IO */
85#define D2S_ZERO 0x01CC /* Digital Counter inside of PHY IO */
86#define D3S_ZERO 0x01D0 /* Digital Counter inside of PHY IO */
87
88#define PPI_CLRFLG 0x01E0 /* PRE Counters has reached set values */
89#define PPI_CLRSIPO 0x01E4 /* Clear SIPO values, Slave mode use only. */
90#define HSTIMEOUT 0x01F0 /* HS Rx Time Out Counter */
91#define HSTIMEOUTENABLE 0x01F4 /* Enable HS Rx Time Out Counter */
92#define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX function */
93#define DSI_RX_START 1
94
95#define DSI_BUSYDSI 0x0208
96#define DSI_LANEENABLE 0x0210 /* Enables each lane at the Protocol layer. */
97#define DSI_LANESTATUS0 0x0214 /* Displays lane is in HS RX mode. */
98#define DSI_LANESTATUS1 0x0218 /* Displays lane is in ULPS or STOP state */
99
100#define DSI_INTSTATUS 0x0220 /* Interrupt Status */
101#define DSI_INTMASK 0x0224 /* Interrupt Mask */
102#define DSI_INTCLR 0x0228 /* Interrupt Clear */
103#define DSI_LPTXTO 0x0230 /* Low Power Tx Time Out Counter */
104
105#define DSIERRCNT 0x0300 /* DSI Error Count */
106#define APLCTRL 0x0400 /* Application Layer Control */
107#define RDPKTLN 0x0404 /* Command Read Packet Length */
108
109#define VPCTRL 0x0450 /* Video Path Control */
110#define HTIM1 0x0454 /* Horizontal Timing Control 1 */
111#define HTIM2 0x0458 /* Horizontal Timing Control 2 */
112#define VTIM1 0x045C /* Vertical Timing Control 1 */
113#define VTIM2 0x0460 /* Vertical Timing Control 2 */
114#define VFUEN 0x0464 /* Video Frame Timing Update Enable */
115#define VFUEN_EN BIT(0) /* Upload Enable */
116
117/* Mux Input Select for LVDS LINK Input */
118#define LV_MX0003 0x0480 /* Bit 0 to 3 */
119#define LV_MX0407 0x0484 /* Bit 4 to 7 */
120#define LV_MX0811 0x0488 /* Bit 8 to 11 */
121#define LV_MX1215 0x048C /* Bit 12 to 15 */
122#define LV_MX1619 0x0490 /* Bit 16 to 19 */
123#define LV_MX2023 0x0494 /* Bit 20 to 23 */
124#define LV_MX2427 0x0498 /* Bit 24 to 27 */
125#define LV_MX(b0, b1, b2, b3) (FLD_VAL(b0, 4, 0) | FLD_VAL(b1, 12, 8) | \
126 FLD_VAL(b2, 20, 16) | FLD_VAL(b3, 28, 24))
127
128/* Input bit numbers used in mux registers */
129enum {
130 LVI_R0,
131 LVI_R1,
132 LVI_R2,
133 LVI_R3,
134 LVI_R4,
135 LVI_R5,
136 LVI_R6,
137 LVI_R7,
138 LVI_G0,
139 LVI_G1,
140 LVI_G2,
141 LVI_G3,
142 LVI_G4,
143 LVI_G5,
144 LVI_G6,
145 LVI_G7,
146 LVI_B0,
147 LVI_B1,
148 LVI_B2,
149 LVI_B3,
150 LVI_B4,
151 LVI_B5,
152 LVI_B6,
153 LVI_B7,
154 LVI_HS,
155 LVI_VS,
156 LVI_DE,
157 LVI_L0
158};
159
160#define LVCFG 0x049C /* LVDS Configuration */
161#define LVPHY0 0x04A0 /* LVDS PHY 0 */
162#define LV_PHY0_RST(v) FLD_VAL(v, 22, 22) /* PHY reset */
163#define LV_PHY0_IS(v) FLD_VAL(v, 15, 14)
164#define LV_PHY0_ND(v) FLD_VAL(v, 4, 0) /* Frequency range select */
165#define LV_PHY0_PRBS_ON(v) FLD_VAL(v, 20, 16) /* Clock/Data Flag pins */
166
167#define LVPHY1 0x04A4 /* LVDS PHY 1 */
168#define SYSSTAT 0x0500 /* System Status */
169#define SYSRST 0x0504 /* System Reset */
170
171#define SYS_RST_I2CS BIT(0) /* Reset I2C-Slave controller */
172#define SYS_RST_I2CM BIT(1) /* Reset I2C-Master controller */
173#define SYS_RST_LCD BIT(2) /* Reset LCD controller */
174#define SYS_RST_BM BIT(3) /* Reset Bus Management controller */
175#define SYS_RST_DSIRX BIT(4) /* Reset DSI-RX and App controller */
176#define SYS_RST_REG BIT(5) /* Reset Register module */
177
178/* GPIO Registers */
179#define GPIOC 0x0520 /* GPIO Control */
180#define GPIOO 0x0524 /* GPIO Output */
181#define GPIOI 0x0528 /* GPIO Input */
182
183/* I2C Registers */
184#define I2CTIMCTRL 0x0540 /* I2C IF Timing and Enable Control */
185#define I2CMADDR 0x0544 /* I2C Master Addressing */
186#define WDATAQ 0x0548 /* Write Data Queue */
187#define RDATAQ 0x054C /* Read Data Queue */
188
189/* Chip ID and Revision ID Register */
190#define IDREG 0x0580
191
192#define LPX_PERIOD 4
193#define TTA_GET 0x40000
194#define TTA_SURE 6
195#define SINGLE_LINK 1
196#define DUAL_LINK 2
197
198#define TC358775XBG_ID 0x00007500
199
200/* Debug Registers */
201#define DEBUG00 0x05A0 /* Debug */
202#define DEBUG01 0x05A4 /* LVDS Data */
203
204#define DSI_CLEN_BIT BIT(0)
205#define DIVIDE_BY_3 3 /* PCLK=DCLK/3 */
206#define DIVIDE_BY_6 6 /* PCLK=DCLK/6 */
207#define LVCFG_LVEN_BIT BIT(0)
208
209#define L0EN BIT(1)
210
211#define TC358775_VPCTRL_VSDELAY__MASK 0x3FF00000
212#define TC358775_VPCTRL_VSDELAY__SHIFT 20
213static inline u32 TC358775_VPCTRL_VSDELAY(uint32_t val)
214{
215 return ((val) << TC358775_VPCTRL_VSDELAY__SHIFT) &
216 TC358775_VPCTRL_VSDELAY__MASK;
217}
218
219#define TC358775_VPCTRL_OPXLFMT__MASK 0x00000100
220#define TC358775_VPCTRL_OPXLFMT__SHIFT 8
221static inline u32 TC358775_VPCTRL_OPXLFMT(uint32_t val)
222{
223 return ((val) << TC358775_VPCTRL_OPXLFMT__SHIFT) &
224 TC358775_VPCTRL_OPXLFMT__MASK;
225}
226
227#define TC358775_VPCTRL_MSF__MASK 0x00000001
228#define TC358775_VPCTRL_MSF__SHIFT 0
229static inline u32 TC358775_VPCTRL_MSF(uint32_t val)
230{
231 return ((val) << TC358775_VPCTRL_MSF__SHIFT) &
232 TC358775_VPCTRL_MSF__MASK;
233}
234
235#define TC358775_LVCFG_PCLKDIV__MASK 0x000000f0
236#define TC358775_LVCFG_PCLKDIV__SHIFT 4
237static inline u32 TC358775_LVCFG_PCLKDIV(uint32_t val)
238{
239 return ((val) << TC358775_LVCFG_PCLKDIV__SHIFT) &
240 TC358775_LVCFG_PCLKDIV__MASK;
241}
242
243#define TC358775_LVCFG_LVDLINK__MASK 0x00000002
244#define TC358775_LVCFG_LVDLINK__SHIFT 0
245static inline u32 TC358775_LVCFG_LVDLINK(uint32_t val)
246{
247 return ((val) << TC358775_LVCFG_LVDLINK__SHIFT) &
248 TC358775_LVCFG_LVDLINK__MASK;
249}
250
251enum tc358775_ports {
252 TC358775_DSI_IN,
253 TC358775_LVDS_OUT0,
254 TC358775_LVDS_OUT1,
255};
256
257struct tc_data {
258 struct i2c_client *i2c;
259 struct device *dev;
260
261 struct drm_bridge bridge;
262 struct drm_bridge *panel_bridge;
263
264 struct device_node *host_node;
265 struct mipi_dsi_device *dsi;
266 u8 num_dsi_lanes;
267
268 struct regulator *vdd;
269 struct regulator *vddio;
270 struct gpio_desc *reset_gpio;
271 struct gpio_desc *stby_gpio;
272 u8 lvds_link; /* single-link or dual-link */
273 u8 bpc;
274};
275
276static inline struct tc_data *bridge_to_tc(struct drm_bridge *b)
277{
278 return container_of(b, struct tc_data, bridge);
279}
280
281static void tc_bridge_pre_enable(struct drm_bridge *bridge)
282{
283 struct tc_data *tc = bridge_to_tc(bridge);
284 struct device *dev = &tc->dsi->dev;
285 int ret;
286
287 ret = regulator_enable(tc->vddio);
288 if (ret < 0)
289 dev_err(dev, "regulator vddio enable failed, %d\n", ret);
290 usleep_range(10000, 11000);
291
292 ret = regulator_enable(tc->vdd);
293 if (ret < 0)
294 dev_err(dev, "regulator vdd enable failed, %d\n", ret);
295 usleep_range(10000, 11000);
296
297 gpiod_set_value(tc->stby_gpio, 0);
298 usleep_range(10000, 11000);
299
300 gpiod_set_value(tc->reset_gpio, 0);
301 usleep_range(10, 20);
302}
303
304static void tc_bridge_post_disable(struct drm_bridge *bridge)
305{
306 struct tc_data *tc = bridge_to_tc(bridge);
307 struct device *dev = &tc->dsi->dev;
308 int ret;
309
310 gpiod_set_value(tc->reset_gpio, 1);
311 usleep_range(10, 20);
312
313 gpiod_set_value(tc->stby_gpio, 1);
314 usleep_range(10000, 11000);
315
316 ret = regulator_disable(tc->vdd);
317 if (ret < 0)
318 dev_err(dev, "regulator vdd disable failed, %d\n", ret);
319 usleep_range(10000, 11000);
320
321 ret = regulator_disable(tc->vddio);
322 if (ret < 0)
323 dev_err(dev, "regulator vddio disable failed, %d\n", ret);
324 usleep_range(10000, 11000);
325}
326
327static void d2l_read(struct i2c_client *i2c, u16 addr, u32 *val)
328{
329 int ret;
330 u8 buf_addr[2];
331
332 put_unaligned_be16(addr, buf_addr);
333 ret = i2c_master_send(i2c, buf_addr, sizeof(buf_addr));
334 if (ret < 0)
335 goto fail;
336
337 ret = i2c_master_recv(i2c, (u8 *)val, sizeof(*val));
338 if (ret < 0)
339 goto fail;
340
341 pr_debug("d2l: I2C : addr:%04x value:%08x\n", addr, *val);
342
343fail:
344 dev_err(&i2c->dev, "Error %d reading from subaddress 0x%x\n",
345 ret, addr);
346}
347
348static void d2l_write(struct i2c_client *i2c, u16 addr, u32 val)
349{
350 u8 data[6];
351 int ret;
352
353 put_unaligned_be16(addr, data);
354 put_unaligned_le32(val, data + 2);
355
356 ret = i2c_master_send(i2c, data, ARRAY_SIZE(data));
357 if (ret < 0)
358 dev_err(&i2c->dev, "Error %d writing to subaddress 0x%x\n",
359 ret, addr);
360}
361
362/* helper function to access bus_formats */
363static struct drm_connector *get_connector(struct drm_encoder *encoder)
364{
365 struct drm_device *dev = encoder->dev;
366 struct drm_connector *connector;
367
368 list_for_each_entry(connector, &dev->mode_config.connector_list, head)
369 if (connector->encoder == encoder)
370 return connector;
371
372 return NULL;
373}
374
375static void tc_bridge_enable(struct drm_bridge *bridge)
376{
377 struct tc_data *tc = bridge_to_tc(bridge);
378 u32 hback_porch, hsync_len, hfront_porch, hactive, htime1, htime2;
379 u32 vback_porch, vsync_len, vfront_porch, vactive, vtime1, vtime2;
380 u32 val = 0;
381 u16 dsiclk, clkdiv, byteclk, t1, t2, t3, vsdelay;
382 struct drm_display_mode *mode;
383 struct drm_connector *connector = get_connector(bridge->encoder);
384
385 mode = &bridge->encoder->crtc->state->adjusted_mode;
386
387 hback_porch = mode->htotal - mode->hsync_end;
388 hsync_len = mode->hsync_end - mode->hsync_start;
389 vback_porch = mode->vtotal - mode->vsync_end;
390 vsync_len = mode->vsync_end - mode->vsync_start;
391
392 htime1 = (hback_porch << 16) + hsync_len;
393 vtime1 = (vback_porch << 16) + vsync_len;
394
395 hfront_porch = mode->hsync_start - mode->hdisplay;
396 hactive = mode->hdisplay;
397 vfront_porch = mode->vsync_start - mode->vdisplay;
398 vactive = mode->vdisplay;
399
400 htime2 = (hfront_porch << 16) + hactive;
401 vtime2 = (vfront_porch << 16) + vactive;
402
403 d2l_read(tc->i2c, IDREG, &val);
404
405 dev_info(tc->dev, "DSI2LVDS Chip ID.%02x Revision ID. %02x **\n",
406 (val >> 8) & 0xFF, val & 0xFF);
407
408 d2l_write(tc->i2c, SYSRST, SYS_RST_REG | SYS_RST_DSIRX | SYS_RST_BM |
409 SYS_RST_LCD | SYS_RST_I2CM | SYS_RST_I2CS);
410 usleep_range(30000, 40000);
411
412 d2l_write(tc->i2c, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
413 d2l_write(tc->i2c, PPI_LPTXTIMECNT, LPX_PERIOD);
414 d2l_write(tc->i2c, PPI_D0S_CLRSIPOCOUNT, 3);
415 d2l_write(tc->i2c, PPI_D1S_CLRSIPOCOUNT, 3);
416 d2l_write(tc->i2c, PPI_D2S_CLRSIPOCOUNT, 3);
417 d2l_write(tc->i2c, PPI_D3S_CLRSIPOCOUNT, 3);
418
419 val = ((L0EN << tc->num_dsi_lanes) - L0EN) | DSI_CLEN_BIT;
420 d2l_write(tc->i2c, PPI_LANEENABLE, val);
421 d2l_write(tc->i2c, DSI_LANEENABLE, val);
422
423 d2l_write(tc->i2c, PPI_STARTPPI, PPI_START_FUNCTION);
424 d2l_write(tc->i2c, DSI_STARTDSI, DSI_RX_START);
425
426 if (tc->bpc == 8)
427 val = TC358775_VPCTRL_OPXLFMT(1);
428 else /* bpc = 6; */
429 val = TC358775_VPCTRL_MSF(1);
430
431 dsiclk = mode->crtc_clock * 3 * tc->bpc / tc->num_dsi_lanes / 1000;
432 clkdiv = dsiclk / DIVIDE_BY_3 * tc->lvds_link;
433 byteclk = dsiclk / 4;
434 t1 = hactive * (tc->bpc * 3 / 8) / tc->num_dsi_lanes;
435 t2 = ((100000 / clkdiv)) * (hactive + hback_porch + hsync_len + hfront_porch) / 1000;
436 t3 = ((t2 * byteclk) / 100) - (hactive * (tc->bpc * 3 / 8) /
437 tc->num_dsi_lanes);
438
439 vsdelay = (clkdiv * (t1 + t3) / byteclk) - hback_porch - hsync_len - hactive;
440
441 val |= TC358775_VPCTRL_VSDELAY(vsdelay);
442 d2l_write(tc->i2c, VPCTRL, val);
443
444 d2l_write(tc->i2c, HTIM1, htime1);
445 d2l_write(tc->i2c, VTIM1, vtime1);
446 d2l_write(tc->i2c, HTIM2, htime2);
447 d2l_write(tc->i2c, VTIM2, vtime2);
448
449 d2l_write(tc->i2c, VFUEN, VFUEN_EN);
450 d2l_write(tc->i2c, SYSRST, SYS_RST_LCD);
451 d2l_write(tc->i2c, LVPHY0, LV_PHY0_PRBS_ON(4) | LV_PHY0_ND(6));
452
453 dev_dbg(tc->dev, "bus_formats %04x bpc %d\n",
454 connector->display_info.bus_formats[0],
455 tc->bpc);
456 /*
457 * Default hardware register settings of tc358775 configured
458 * with MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA jeida-24 format
459 */
460 if (connector->display_info.bus_formats[0] ==
461 MEDIA_BUS_FMT_RGB888_1X7X4_SPWG) {
462 /* VESA-24 */
463 d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
464 d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_R7, LVI_R5, LVI_G0));
465 d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_G6, LVI_G7));
466 d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
467 d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_B6, LVI_B7, LVI_B1, LVI_B2));
468 d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
469 d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_R6));
470 } else { /* MEDIA_BUS_FMT_RGB666_1X7X3_SPWG - JEIDA-18 */
471 d2l_write(tc->i2c, LV_MX0003, LV_MX(LVI_R0, LVI_R1, LVI_R2, LVI_R3));
472 d2l_write(tc->i2c, LV_MX0407, LV_MX(LVI_R4, LVI_L0, LVI_R5, LVI_G0));
473 d2l_write(tc->i2c, LV_MX0811, LV_MX(LVI_G1, LVI_G2, LVI_L0, LVI_L0));
474 d2l_write(tc->i2c, LV_MX1215, LV_MX(LVI_G3, LVI_G4, LVI_G5, LVI_B0));
475 d2l_write(tc->i2c, LV_MX1619, LV_MX(LVI_L0, LVI_L0, LVI_B1, LVI_B2));
476 d2l_write(tc->i2c, LV_MX2023, LV_MX(LVI_B3, LVI_B4, LVI_B5, LVI_L0));
477 d2l_write(tc->i2c, LV_MX2427, LV_MX(LVI_HS, LVI_VS, LVI_DE, LVI_L0));
478 }
479
480 d2l_write(tc->i2c, VFUEN, VFUEN_EN);
481
482 val = LVCFG_LVEN_BIT;
483 if (tc->lvds_link == DUAL_LINK) {
484 val |= TC358775_LVCFG_LVDLINK(1);
485 val |= TC358775_LVCFG_PCLKDIV(DIVIDE_BY_6);
486 } else {
487 val |= TC358775_LVCFG_PCLKDIV(DIVIDE_BY_3);
488 };
489 d2l_write(tc->i2c, LVCFG, val);
490}
491
492static enum drm_mode_status
493tc_mode_valid(struct drm_bridge *bridge,
494 const struct drm_display_info *info,
495 const struct drm_display_mode *mode)
496{
497 struct tc_data *tc = bridge_to_tc(bridge);
498
499 /*
500 * Maximum pixel clock speed 135MHz for single-link
501 * 270MHz for dual-link
502 */
503 if ((mode->clock > 135000 && tc->lvds_link == SINGLE_LINK) ||
504 (mode->clock > 270000 && tc->lvds_link == DUAL_LINK))
505 return MODE_CLOCK_HIGH;
506
507 switch (info->bus_formats[0]) {
508 case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
509 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
510 /* RGB888 */
511 tc->bpc = 8;
512 break;
513 case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
514 /* RGB666 */
515 tc->bpc = 6;
516 break;
517 default:
518 dev_warn(tc->dev,
519 "unsupported LVDS bus format 0x%04x\n",
520 info->bus_formats[0]);
521 return MODE_NOMODE;
522 }
523
524 return MODE_OK;
525}
526
527static int tc358775_parse_dt(struct device_node *np, struct tc_data *tc)
528{
529 struct device_node *endpoint;
530 struct device_node *parent;
531 struct device_node *remote;
532 struct property *prop;
533 int len = 0;
534
535 /*
536 * To get the data-lanes of dsi, we need to access the dsi0_out of port1
537 * of dsi0 endpoint from bridge port0 of d2l_in
538 */
539 endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
540 TC358775_DSI_IN, -1);
541 if (endpoint) {
542 /* dsi0_out node */
543 parent = of_graph_get_remote_port_parent(endpoint);
544 of_node_put(endpoint);
545 if (parent) {
546 /* dsi0 port 1 */
547 endpoint = of_graph_get_endpoint_by_regs(parent, 1, -1);
548 of_node_put(parent);
549 if (endpoint) {
550 prop = of_find_property(endpoint, "data-lanes",
551 &len);
552 of_node_put(endpoint);
553 if (!prop) {
554 dev_err(tc->dev,
555 "failed to find data lane\n");
556 return -EPROBE_DEFER;
557 }
558 }
559 }
560 }
561
562 tc->num_dsi_lanes = len / sizeof(u32);
563
564 if (tc->num_dsi_lanes < 1 || tc->num_dsi_lanes > 4)
565 return -EINVAL;
566
567 tc->host_node = of_graph_get_remote_node(np, 0, 0);
568 if (!tc->host_node)
569 return -ENODEV;
570
571 of_node_put(tc->host_node);
572
573 tc->lvds_link = SINGLE_LINK;
574 endpoint = of_graph_get_endpoint_by_regs(tc->dev->of_node,
575 TC358775_LVDS_OUT1, -1);
576 if (endpoint) {
577 remote = of_graph_get_remote_port_parent(endpoint);
578 of_node_put(endpoint);
579
580 if (remote) {
581 if (of_device_is_available(remote))
582 tc->lvds_link = DUAL_LINK;
583 of_node_put(remote);
584 }
585 }
586
587 dev_dbg(tc->dev, "no.of dsi lanes: %d\n", tc->num_dsi_lanes);
588 dev_dbg(tc->dev, "operating in %d-link mode\n", tc->lvds_link);
589
590 return 0;
591}
592
593static int tc_bridge_attach(struct drm_bridge *bridge,
594 enum drm_bridge_attach_flags flags)
595{
596 struct tc_data *tc = bridge_to_tc(bridge);
597 struct device *dev = &tc->i2c->dev;
598 struct mipi_dsi_host *host;
599 struct mipi_dsi_device *dsi;
600 int ret;
601
602 const struct mipi_dsi_device_info info = { .type = "tc358775",
603 .channel = 0,
604 .node = NULL,
605 };
606
607 host = of_find_mipi_dsi_host_by_node(tc->host_node);
608 if (!host) {
609 dev_err(dev, "failed to find dsi host\n");
610 return -EPROBE_DEFER;
611 }
612
613 dsi = mipi_dsi_device_register_full(host, &info);
614 if (IS_ERR(dsi)) {
615 dev_err(dev, "failed to create dsi device\n");
616 ret = PTR_ERR(dsi);
617 goto err_dsi_device;
618 }
619
620 tc->dsi = dsi;
621
622 dsi->lanes = tc->num_dsi_lanes;
623 dsi->format = MIPI_DSI_FMT_RGB888;
624 dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
625
626 ret = mipi_dsi_attach(dsi);
627 if (ret < 0) {
628 dev_err(dev, "failed to attach dsi to host\n");
629 goto err_dsi_attach;
630 }
631
632 /* Attach the panel-bridge to the dsi bridge */
633 return drm_bridge_attach(bridge->encoder, tc->panel_bridge,
634 &tc->bridge, flags);
635err_dsi_attach:
636 mipi_dsi_device_unregister(dsi);
637err_dsi_device:
638 return ret;
639}
640
641static const struct drm_bridge_funcs tc_bridge_funcs = {
642 .attach = tc_bridge_attach,
643 .pre_enable = tc_bridge_pre_enable,
644 .enable = tc_bridge_enable,
645 .mode_valid = tc_mode_valid,
646 .post_disable = tc_bridge_post_disable,
647};
648
649static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
650{
651 struct device *dev = &client->dev;
652 struct drm_panel *panel;
653 struct tc_data *tc;
654 int ret;
655
656 tc = devm_kzalloc(dev, sizeof(*tc), GFP_KERNEL);
657 if (!tc)
658 return -ENOMEM;
659
660 tc->dev = dev;
661 tc->i2c = client;
662
663 ret = drm_of_find_panel_or_bridge(dev->of_node, TC358775_LVDS_OUT0,
664 0, &panel, NULL);
665 if (ret < 0)
666 return ret;
667 if (!panel)
668 return -ENODEV;
669
670 tc->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
671 if (IS_ERR(tc->panel_bridge))
672 return PTR_ERR(tc->panel_bridge);
673
674 ret = tc358775_parse_dt(dev->of_node, tc);
675 if (ret)
676 return ret;
677
678 tc->vddio = devm_regulator_get(dev, "vddio-supply");
679 if (IS_ERR(tc->vddio)) {
680 ret = PTR_ERR(tc->vddio);
681 dev_err(dev, "vddio-supply not found\n");
682 return ret;
683 }
684
685 tc->vdd = devm_regulator_get(dev, "vdd-supply");
686 if (IS_ERR(tc->vdd)) {
687 ret = PTR_ERR(tc->vdd);
688 dev_err(dev, "vdd-supply not found\n");
689 return ret;
690 }
691
692 tc->stby_gpio = devm_gpiod_get(dev, "stby", GPIOD_OUT_HIGH);
693 if (IS_ERR(tc->stby_gpio)) {
694 ret = PTR_ERR(tc->stby_gpio);
695 dev_err(dev, "cannot get stby-gpio %d\n", ret);
696 return ret;
697 }
698
699 tc->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
700 if (IS_ERR(tc->reset_gpio)) {
701 ret = PTR_ERR(tc->reset_gpio);
702 dev_err(dev, "cannot get reset-gpios %d\n", ret);
703 return ret;
704 }
705
706 tc->bridge.funcs = &tc_bridge_funcs;
707 tc->bridge.of_node = dev->of_node;
708 drm_bridge_add(&tc->bridge);
709
710 i2c_set_clientdata(client, tc);
711
712 return 0;
713}
714
715static int tc_remove(struct i2c_client *client)
716{
717 struct tc_data *tc = i2c_get_clientdata(client);
718
719 drm_bridge_remove(&tc->bridge);
720
721 return 0;
722}
723
724static const struct i2c_device_id tc358775_i2c_ids[] = {
725 { "tc358775", 0 },
726 { }
727};
728MODULE_DEVICE_TABLE(i2c, tc358775_i2c_ids);
729
730static const struct of_device_id tc358775_of_ids[] = {
731 { .compatible = "toshiba,tc358775", },
732 { }
733};
734MODULE_DEVICE_TABLE(of, tc358775_of_ids);
735
736static struct i2c_driver tc358775_driver = {
737 .driver = {
738 .name = "tc358775",
739 .of_match_table = tc358775_of_ids,
740 },
741 .id_table = tc358775_i2c_ids,
742 .probe = tc_probe,
743 .remove = tc_remove,
744};
745module_i2c_driver(tc358775_driver);
746
747MODULE_AUTHOR("Vinay Simha BN <simhavcs@gmail.com>");
748MODULE_DESCRIPTION("TC358775 DSI/LVDS bridge driver");
749MODULE_LICENSE("GPL v2");
drivers/gpu/drm/bridge/ti-sn65dsi86.c+0−3
@@ -394,9 +394,6 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge, · 393 unmodified lines
394 }394 }
395 pdata->dsi = dsi;395 pdata->dsi = dsi;
396 396
397 /* attach panel to bridge */
398 drm_panel_attach(pdata->panel, &pdata->connector);
399
400 return 0;397 return 0;
401 398
402err_dsi_attach:399err_dsi_attach:
drivers/gpu/drm/drm_bridge_connector.c+1−0
@@ -187,6 +187,7 @@ drm_bridge_connector_detect(struct drm_connector *connector, bool force) · 186 unmodified lines
187 case DRM_MODE_CONNECTOR_DPI:187 case DRM_MODE_CONNECTOR_DPI:
188 case DRM_MODE_CONNECTOR_LVDS:188 case DRM_MODE_CONNECTOR_LVDS:
189 case DRM_MODE_CONNECTOR_DSI:189 case DRM_MODE_CONNECTOR_DSI:
190 case DRM_MODE_CONNECTOR_eDP:
190 status = connector_status_connected;191 status = connector_status_connected;
191 break;192 break;
192 default:193 default:
drivers/gpu/drm/drm_connector.c+47−2
@@ -850,7 +850,7 @@ static const struct drm_prop_enum_list drm_dvi_i_select_enum_list[] = { · 849 unmodified lines
850DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)850DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
851 851
852static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {852static const struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] = {
853 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */853 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I, TV-out and DP */
854 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */854 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
855 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */855 { DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
856};856};
@@ -867,7 +867,7 @@ static const struct drm_prop_enum_list drm_tv_select_enum_list[] = { · 10 unmodified lines
867DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)867DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
868 868
869static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {869static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
870 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */870 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I, TV-out and DP */
871 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */871 { DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
872 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */872 { DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
873 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */873 { DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
@@ -876,6 +876,19 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = { · 2 unmodified lines
876DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,876DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
877 drm_tv_subconnector_enum_list)877 drm_tv_subconnector_enum_list)
878 878
879static const struct drm_prop_enum_list drm_dp_subconnector_enum_list[] = {
880 { DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I, TV-out and DP */
881 { DRM_MODE_SUBCONNECTOR_VGA, "VGA" }, /* DP */
882 { DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DP */
883 { DRM_MODE_SUBCONNECTOR_HDMIA, "HDMI" }, /* DP */
884 { DRM_MODE_SUBCONNECTOR_DisplayPort, "DP" }, /* DP */
885 { DRM_MODE_SUBCONNECTOR_Wireless, "Wireless" }, /* DP */
886 { DRM_MODE_SUBCONNECTOR_Native, "Native" }, /* DP */
887};
888
889DRM_ENUM_NAME_FN(drm_get_dp_subconnector_name,
890 drm_dp_subconnector_enum_list)
891
879static const struct drm_prop_enum_list hdmi_colorspaces[] = {892static const struct drm_prop_enum_list hdmi_colorspaces[] = {
880 /* For Default case, driver will set the colorspace */893 /* For Default case, driver will set the colorspace */
881 { DRM_MODE_COLORIMETRY_DEFAULT, "Default" },894 { DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
@@ -1217,6 +1230,14 @@ static const struct drm_prop_enum_list dp_colorspaces[] = { · 335 unmodified lines
1217 * can also expose this property to external outputs, in which case they1230 * can also expose this property to external outputs, in which case they
1218 * must support "None", which should be the default (since external screens1231 * must support "None", which should be the default (since external screens
1219 * have a built-in scaler).1232 * have a built-in scaler).
1233 *
1234 * subconnector:
1235 * This property is used by DVI-I, TVout and DisplayPort to indicate different
1236 * connector subtypes. Enum values more or less match with those from main
1237 * connector types.
1238 * For DVI-I and TVout there is also a matching property "select subconnector"
1239 * allowing to switch between signal types.
1240 * DP subconnector corresponds to a downstream port.
1220 */1241 */
1221 1242
1222int drm_connector_create_standard_properties(struct drm_device *dev)1243int drm_connector_create_standard_properties(struct drm_device *dev)
@@ -1305,6 +1326,30 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev) · 82 unmodified lines
1305}1326}
1306EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);1327EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
1307 1328
1329/**
1330 * drm_connector_attach_dp_subconnector_property - create subconnector property for DP
1331 * @connector: drm_connector to attach property
1332 *
1333 * Called by a driver when DP connector is created.
1334 */
1335void drm_connector_attach_dp_subconnector_property(struct drm_connector *connector)
1336{
1337 struct drm_mode_config *mode_config = &connector->dev->mode_config;
1338
1339 if (!mode_config->dp_subconnector_property)
1340 mode_config->dp_subconnector_property =
1341 drm_property_create_enum(connector->dev,
1342 DRM_MODE_PROP_IMMUTABLE,
1343 "subconnector",
1344 drm_dp_subconnector_enum_list,
1345 ARRAY_SIZE(drm_dp_subconnector_enum_list));
1346
1347 drm_object_attach_property(&connector->base,
1348 mode_config->dp_subconnector_property,
1349 DRM_MODE_SUBCONNECTOR_Unknown);
1350}
1351EXPORT_SYMBOL(drm_connector_attach_dp_subconnector_property);
1352
1308/**1353/**
1309 * DOC: HDMI connector properties1354 * DOC: HDMI connector properties
1310 *1355 *
drivers/gpu/drm/drm_dp_helper.c+71−0
@@ -597,6 +597,77 @@ void drm_dp_downstream_debug(struct seq_file *m, · 596 unmodified lines
597}597}
598EXPORT_SYMBOL(drm_dp_downstream_debug);598EXPORT_SYMBOL(drm_dp_downstream_debug);
599 599
600/**
601 * drm_dp_subconnector_type() - get DP branch device type
602 *
603 */
604enum drm_mode_subconnector
605drm_dp_subconnector_type(const u8 dpcd[DP_RECEIVER_CAP_SIZE],
606 const u8 port_cap[4])
607{
608 int type;
609 if (!drm_dp_is_branch(dpcd))
610 return DRM_MODE_SUBCONNECTOR_Native;
611 /* DP 1.0 approach */
612 if (dpcd[DP_DPCD_REV] == DP_DPCD_REV_10) {
613 type = dpcd[DP_DOWNSTREAMPORT_PRESENT] &
614 DP_DWN_STRM_PORT_TYPE_MASK;
615
616 switch (type) {
617 case DP_DWN_STRM_PORT_TYPE_TMDS:
618 /* Can be HDMI or DVI-D, DVI-D is a safer option */
619 return DRM_MODE_SUBCONNECTOR_DVID;
620 case DP_DWN_STRM_PORT_TYPE_ANALOG:
621 /* Can be VGA or DVI-A, VGA is more popular */
622 return DRM_MODE_SUBCONNECTOR_VGA;
623 case DP_DWN_STRM_PORT_TYPE_DP:
624 return DRM_MODE_SUBCONNECTOR_DisplayPort;
625 case DP_DWN_STRM_PORT_TYPE_OTHER:
626 default:
627 return DRM_MODE_SUBCONNECTOR_Unknown;
628 }
629 }
630 type = port_cap[0] & DP_DS_PORT_TYPE_MASK;
631
632 switch (type) {
633 case DP_DS_PORT_TYPE_DP:
634 case DP_DS_PORT_TYPE_DP_DUALMODE:
635 return DRM_MODE_SUBCONNECTOR_DisplayPort;
636 case DP_DS_PORT_TYPE_VGA:
637 return DRM_MODE_SUBCONNECTOR_VGA;
638 case DP_DS_PORT_TYPE_DVI:
639 return DRM_MODE_SUBCONNECTOR_DVID;
640 case DP_DS_PORT_TYPE_HDMI:
641 return DRM_MODE_SUBCONNECTOR_HDMIA;
642 case DP_DS_PORT_TYPE_WIRELESS:
643 return DRM_MODE_SUBCONNECTOR_Wireless;
644 case DP_DS_PORT_TYPE_NON_EDID:
645 default:
646 return DRM_MODE_SUBCONNECTOR_Unknown;
647 }
648}
649EXPORT_SYMBOL(drm_dp_subconnector_type);
650
651/**
652 * drm_mode_set_dp_subconnector_property - set subconnector for DP connector
653 *
654 * Called by a driver on every detect event.
655 */
656void drm_dp_set_subconnector_property(struct drm_connector *connector,
657 enum drm_connector_status status,
658 const u8 *dpcd,
659 const u8 port_cap[4])
660{
661 enum drm_mode_subconnector subconnector = DRM_MODE_SUBCONNECTOR_Unknown;
662
663 if (status == connector_status_connected)
664 subconnector = drm_dp_subconnector_type(dpcd, port_cap);
665 drm_object_property_set_value(&connector->base,
666 connector->dev->mode_config.dp_subconnector_property,
667 subconnector);
668}
669EXPORT_SYMBOL(drm_dp_set_subconnector_property);
670
600/*671/*
601 * I2C-over-AUX implementation672 * I2C-over-AUX implementation
602 */673 */
drivers/gpu/drm/drm_gem_vram_helper.c+10−39
@@ -653,7 +653,7 @@ static void drm_gem_vram_bo_driver_evict_flags(struct drm_gem_vram_object *gbo, · 652 unmodified lines
653 653
654static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,654static void drm_gem_vram_bo_driver_move_notify(struct drm_gem_vram_object *gbo,
655 bool evict,655 bool evict,
656 struct ttm_mem_reg *new_mem)656 struct ttm_resource *new_mem)
657{657{
658 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;658 struct ttm_bo_kmap_obj *kmap = &gbo->kmap;
659 659
@@ -1004,28 +1004,6 @@ err_ttm_tt_init: · 344 unmodified lines
1004 return NULL;1004 return NULL;
1005}1005}
1006 1006
1007static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
1008 struct ttm_mem_type_manager *man)
1009{
1010 switch (type) {
1011 case TTM_PL_SYSTEM:
1012 man->flags = 0;
1013 man->available_caching = TTM_PL_MASK_CACHING;
1014 man->default_caching = TTM_PL_FLAG_CACHED;
1015 break;
1016 case TTM_PL_VRAM:
1017 man->func = &ttm_bo_manager_func;
1018 man->flags = TTM_MEMTYPE_FLAG_FIXED;
1019 man->available_caching = TTM_PL_FLAG_UNCACHED |
1020 TTM_PL_FLAG_WC;
1021 man->default_caching = TTM_PL_FLAG_WC;
1022 break;
1023 default:
1024 return -EINVAL;
1025 }
1026 return 0;
1027}
1028
1029static void bo_driver_evict_flags(struct ttm_buffer_object *bo,1007static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
1030 struct ttm_placement *placement)1008 struct ttm_placement *placement)
1031{1009{
@@ -1042,7 +1020,7 @@ static void bo_driver_evict_flags(struct ttm_buffer_object *bo, · 10 unmodified lines
1042 1020
1043static void bo_driver_move_notify(struct ttm_buffer_object *bo,1021static void bo_driver_move_notify(struct ttm_buffer_object *bo,
1044 bool evict,1022 bool evict,
1045 struct ttm_mem_reg *new_mem)1023 struct ttm_resource *new_mem)
1046{1024{
1047 struct drm_gem_vram_object *gbo;1025 struct drm_gem_vram_object *gbo;
1048 1026
@@ -1056,18 +1034,12 @@ static void bo_driver_move_notify(struct ttm_buffer_object *bo, · 7 unmodified lines
1056}1034}
1057 1035
1058static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,1036static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
1059 struct ttm_mem_reg *mem)1037 struct ttm_resource *mem)
1060{1038{
1061 struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);1039 struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
1062 1040
1063 mem->bus.addr = NULL;
1064 mem->bus.size = mem->num_pages << PAGE_SHIFT;
1065
1066 switch (mem->mem_type) {1041 switch (mem->mem_type) {
1067 case TTM_PL_SYSTEM: /* nothing to do */1042 case TTM_PL_SYSTEM: /* nothing to do */
1068 mem->bus.offset = 0;
1069 mem->bus.base = 0;
1070 mem->bus.is_iomem = false;
1071 break;1043 break;
1072 case TTM_PL_VRAM:1044 case TTM_PL_VRAM:
1073 mem->bus.offset = mem->start << PAGE_SHIFT;1045 mem->bus.offset = mem->start << PAGE_SHIFT;
@@ -1083,9 +1055,6 @@ static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev, · 9 unmodified lines
1083 1055
1084static struct ttm_bo_driver bo_driver = {1056static struct ttm_bo_driver bo_driver = {
1085 .ttm_tt_create = bo_driver_ttm_tt_create,1057 .ttm_tt_create = bo_driver_ttm_tt_create,
1086 .ttm_tt_populate = ttm_pool_populate,
1087 .ttm_tt_unpopulate = ttm_pool_unpopulate,
1088 .init_mem_type = bo_driver_init_mem_type,
1089 .eviction_valuable = ttm_bo_eviction_valuable,1058 .eviction_valuable = ttm_bo_eviction_valuable,
1090 .evict_flags = bo_driver_evict_flags,1059 .evict_flags = bo_driver_evict_flags,
1091 .move_notify = bo_driver_move_notify,1060 .move_notify = bo_driver_move_notify,
@@ -1100,12 +1069,10 @@ static int drm_vram_mm_debugfs(struct seq_file *m, void *data) · 8 unmodified lines
1100{1069{
1101 struct drm_info_node *node = (struct drm_info_node *) m->private;1070 struct drm_info_node *node = (struct drm_info_node *) m->private;
1102 struct drm_vram_mm *vmm = node->minor->dev->vram_mm;1071 struct drm_vram_mm *vmm = node->minor->dev->vram_mm;
1103 struct drm_mm *mm = vmm->bdev.man[TTM_PL_VRAM].priv;1072 struct ttm_resource_manager *man = ttm_manager_type(&vmm->bdev, TTM_PL_VRAM);
1104 struct drm_printer p = drm_seq_file_printer(m);1073 struct drm_printer p = drm_seq_file_printer(m);
1105 1074
1106 spin_lock(&ttm_bo_glob.lru_lock);1075 ttm_resource_manager_debug(man, &p);
1107 drm_mm_print(mm, &p);
1108 spin_unlock(&ttm_bo_glob.lru_lock);
1109 return 0;1076 return 0;
1110}1077}
1111 1078
@@ -1142,7 +1109,10 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev, · 30 unmodified lines
1142 if (ret)1109 if (ret)
1143 return ret;1110 return ret;
1144 1111
1145 ret = ttm_bo_init_mm(&vmm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);1112 ret = ttm_range_man_init(&vmm->bdev, TTM_PL_VRAM,
1113 TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
1114 TTM_PL_FLAG_WC, false,
1115 vram_size >> PAGE_SHIFT);
1146 if (ret)1116 if (ret)
1147 return ret;1117 return ret;
1148 1118
@@ -1151,6 +1121,7 @@ static int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev, · 2 unmodified lines
1151 1121
1152static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)1122static void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
1153{1123{
1124 ttm_range_man_fini(&vmm->bdev, TTM_PL_VRAM);
1154 ttm_bo_device_release(&vmm->bdev);1125 ttm_bo_device_release(&vmm->bdev);
1155}1126}
1156 1127
drivers/gpu/drm/drm_panel.c+44−41
@@ -70,16 +70,12 @@ EXPORT_SYMBOL(drm_panel_init); · 69 unmodified lines
70 *70 *
71 * Add a panel to the global registry so that it can be looked up by display71 * Add a panel to the global registry so that it can be looked up by display
72 * drivers.72 * drivers.
73 *
74 * Return: 0 on success or a negative error code on failure.
75 */73 */
76int drm_panel_add(struct drm_panel *panel)74void drm_panel_add(struct drm_panel *panel)
77{75{
78 mutex_lock(&panel_lock);76 mutex_lock(&panel_lock);
79 list_add_tail(&panel->list, &panel_list);77 list_add_tail(&panel->list, &panel_list);
80 mutex_unlock(&panel_lock);78 mutex_unlock(&panel_lock);
81
82 return 0;
83}79}
84EXPORT_SYMBOL(drm_panel_add);80EXPORT_SYMBOL(drm_panel_add);
85 81
@@ -97,42 +93,6 @@ void drm_panel_remove(struct drm_panel *panel) · 11 unmodified lines
97}93}
98EXPORT_SYMBOL(drm_panel_remove);94EXPORT_SYMBOL(drm_panel_remove);
99 95
100/**
101 * drm_panel_attach - attach a panel to a connector
102 * @panel: DRM panel
103 * @connector: DRM connector
104 *
105 * After obtaining a pointer to a DRM panel a display driver calls this
106 * function to attach a panel to a connector.
107 *
108 * An error is returned if the panel is already attached to another connector.
109 *
110 * When unloading, the driver should detach from the panel by calling
111 * drm_panel_detach().
112 *
113 * Return: 0 on success or a negative error code on failure.
114 */
115int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
116{
117 return 0;
118}
119EXPORT_SYMBOL(drm_panel_attach);
120
121/**
122 * drm_panel_detach - detach a panel from a connector
123 * @panel: DRM panel
124 *
125 * Detaches a panel from the connector it is attached to. If a panel is not
126 * attached to any connector this is effectively a no-op.
127 *
128 * This function should not be called by the panel device itself. It
129 * is only for the drm device that called drm_panel_attach().
130 */
131void drm_panel_detach(struct drm_panel *panel)
132{
133}
134EXPORT_SYMBOL(drm_panel_detach);
135
136/**96/**
137 * drm_panel_prepare - power on a panel97 * drm_panel_prepare - power on a panel
138 * @panel: DRM panel98 * @panel: DRM panel
@@ -300,6 +260,49 @@ struct drm_panel *of_drm_find_panel(const struct device_node *np) · 161 unmodified lines
300 return ERR_PTR(-EPROBE_DEFER);260 return ERR_PTR(-EPROBE_DEFER);
301}261}
302EXPORT_SYMBOL(of_drm_find_panel);262EXPORT_SYMBOL(of_drm_find_panel);
263
264/**
265 * of_drm_get_panel_orientation - look up the orientation of the panel through
266 * the "rotation" binding from a device tree node
267 * @np: device tree node of the panel
268 * @orientation: orientation enum to be filled in
269 *
270 * Looks up the rotation of a panel in the device tree. The orientation of the
271 * panel is expressed as a property name "rotation" in the device tree. The
272 * rotation in the device tree is counter clockwise.
273 *
274 * Return: 0 when a valid rotation value (0, 90, 180, or 270) is read or the
275 * rotation property doesn't exist. Return a negative error code on failure.
276 */
277int of_drm_get_panel_orientation(const struct device_node *np,
278 enum drm_panel_orientation *orientation)
279{
280 int rotation, ret;
281
282 ret = of_property_read_u32(np, "rotation", &rotation);
283 if (ret == -EINVAL) {
284 /* Don't return an error if there's no rotation property. */
285 *orientation = DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
286 return 0;
287 }
288
289 if (ret < 0)
290 return ret;
291
292 if (rotation == 0)
293 *orientation = DRM_MODE_PANEL_ORIENTATION_NORMAL;
294 else if (rotation == 90)
295 *orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP;
296 else if (rotation == 180)
297 *orientation = DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP;
298 else if (rotation == 270)
299 *orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP;
300 else
301 return -EINVAL;
302
303 return 0;
304}
305EXPORT_SYMBOL(of_drm_get_panel_orientation);
303#endif306#endif
304 307
305#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)308#if IS_REACHABLE(CONFIG_BACKLIGHT_CLASS_DEVICE)
drivers/gpu/drm/drm_syncobj.c+1−1
@@ -297,7 +297,7 @@ void drm_syncobj_add_point(struct drm_syncobj *syncobj, · 296 unmodified lines
297 prev = drm_syncobj_fence_get(syncobj);297 prev = drm_syncobj_fence_get(syncobj);
298 /* You are adding an unorder point to timeline, which could cause payload returned from query_ioctl is 0! */298 /* You are adding an unorder point to timeline, which could cause payload returned from query_ioctl is 0! */
299 if (prev && prev->seqno >= point)299 if (prev && prev->seqno >= point)
300 DRM_ERROR("You are adding an unorder point to timeline!\n");300 DRM_DEBUG("You are adding an unorder point to timeline!\n");
301 dma_fence_chain_init(chain, prev, fence, point);301 dma_fence_chain_init(chain, prev, fence, point);
302 rcu_assign_pointer(syncobj->fence, &chain->base);302 rcu_assign_pointer(syncobj->fence, &chain->base);
303 303
drivers/gpu/drm/exynos/exynos_drm_dpi.c+0−8
@@ -42,11 +42,6 @@ static inline struct exynos_dpi *encoder_to_dpi(struct drm_encoder *e) · 41 unmodified lines
42static enum drm_connector_status42static enum drm_connector_status
43exynos_dpi_detect(struct drm_connector *connector, bool force)43exynos_dpi_detect(struct drm_connector *connector, bool force)
44{44{
45 struct exynos_dpi *ctx = connector_to_dpi(connector);
46
47 if (ctx->panel)
48 drm_panel_attach(ctx->panel, &ctx->connector);
49
50 return connector_status_connected;45 return connector_status_connected;
51}46}
52 47
@@ -249,8 +244,5 @@ int exynos_dpi_remove(struct drm_encoder *encoder) · 196 unmodified lines
249 244
250 exynos_dpi_disable(&ctx->encoder);245 exynos_dpi_disable(&ctx->encoder);
251 246
252 if (ctx->panel)
253 drm_panel_detach(ctx->panel);
254
255 return 0;247 return 0;
256}248}
drivers/gpu/drm/exynos/exynos_drm_dsi.c+2−5
@@ -1551,12 +1551,10 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, · 1550 unmodified lines
1551 }1551 }
1552 1552
1553 dsi->panel = of_drm_find_panel(device->dev.of_node);1553 dsi->panel = of_drm_find_panel(device->dev.of_node);
1554 if (IS_ERR(dsi->panel)) {1554 if (IS_ERR(dsi->panel))
1555 dsi->panel = NULL;1555 dsi->panel = NULL;
1556 } else {1556 else
1557 drm_panel_attach(dsi->panel, &dsi->connector);
1558 dsi->connector.status = connector_status_connected;1557 dsi->connector.status = connector_status_connected;
1559 }
1560 }1558 }
1561 1559
1562 /*1560 /*
@@ -1596,7 +1594,6 @@ static int exynos_dsi_host_detach(struct mipi_dsi_host *host, · 33 unmodified lines
1596 if (dsi->panel) {1594 if (dsi->panel) {
1597 mutex_lock(&drm->mode_config.mutex);1595 mutex_lock(&drm->mode_config.mutex);
1598 exynos_dsi_disable(&dsi->encoder);1596 exynos_dsi_disable(&dsi->encoder);
1599 drm_panel_detach(dsi->panel);
1600 dsi->panel = NULL;1597 dsi->panel = NULL;
1601 dsi->connector.status = connector_status_disconnected;1598 dsi->connector.status = connector_status_disconnected;
1602 mutex_unlock(&drm->mode_config.mutex);1599 mutex_unlock(&drm->mode_config.mutex);
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c+0−9
@@ -40,10 +40,7 @@ int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev, · 39 unmodified lines
40 40
41static void fsl_dcu_drm_connector_destroy(struct drm_connector *connector)41static void fsl_dcu_drm_connector_destroy(struct drm_connector *connector)
42{42{
43 struct fsl_dcu_drm_connector *fsl_con = to_fsl_dcu_connector(connector);
44
45 drm_connector_unregister(connector);43 drm_connector_unregister(connector);
46 drm_panel_detach(fsl_con->panel);
47 drm_connector_cleanup(connector);44 drm_connector_cleanup(connector);
48}45}
49 46
@@ -101,12 +98,6 @@ static int fsl_dcu_attach_panel(struct fsl_dcu_drm_device *fsl_dev, · 51 unmodified lines
101 if (ret < 0)98 if (ret < 0)
102 goto err_sysfs;99 goto err_sysfs;
103 100
104 ret = drm_panel_attach(panel, connector);
105 if (ret) {
106 dev_err(fsl_dev->dev, "failed to attach panel\n");
107 goto err_sysfs;
108 }
109
110 return 0;101 return 0;
111 102
112err_sysfs:103err_sysfs:
drivers/gpu/drm/gma500/cdv_intel_dp.c+1−1
@@ -2078,7 +2078,7 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev · 2077 unmodified lines
2078 intel_dp->dpcd,2078 intel_dp->dpcd,
2079 sizeof(intel_dp->dpcd));2079 sizeof(intel_dp->dpcd));
2080 cdv_intel_edp_panel_vdd_off(gma_encoder);2080 cdv_intel_edp_panel_vdd_off(gma_encoder);
2081 if (ret == 0) {2081 if (ret <= 0) {
2082 /* if this fails, presume the device is a ghost */2082 /* if this fails, presume the device is a ghost */
2083 DRM_INFO("failed to retrieve link info, disabling eDP\n");2083 DRM_INFO("failed to retrieve link info, disabling eDP\n");
2084 drm_encoder_cleanup(encoder);2084 drm_encoder_cleanup(encoder);
drivers/gpu/drm/gma500/mdfld_device.c+20−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 **************************************************************************/6 **************************************************************************/
7 7
8#include <linux/delay.h>8#include <linux/delay.h>
9#include <linux/gpio/machine.h>
9 10
10#include <asm/intel_scu_ipc.h>11#include <asm/intel_scu_ipc.h>
11 12
@@ -505,12 +506,31 @@ static const struct psb_offset mdfld_regmap[3] = { · 493 unmodified lines
505 },506 },
506};507};
507 508
509/*
510 * The GPIO lines for resetting DSI pipe 0 and 2 are available in the
511 * PCI device 0000:00:0c.0 on the Medfield.
512 */
513static struct gpiod_lookup_table mdfld_dsi_pipe_gpio_table = {
514 .table = {
515 GPIO_LOOKUP("0000:00:0c.0", 128, "dsi-pipe0-reset",
516 GPIO_ACTIVE_HIGH),
517 GPIO_LOOKUP("0000:00:0c.0", 34, "dsi-pipe2-reset",
518 GPIO_ACTIVE_HIGH),
519 { },
520 },
521};
522
508static int mdfld_chip_setup(struct drm_device *dev)523static int mdfld_chip_setup(struct drm_device *dev)
509{524{
510 struct drm_psb_private *dev_priv = dev->dev_private;525 struct drm_psb_private *dev_priv = dev->dev_private;
511 if (pci_enable_msi(dev->pdev))526 if (pci_enable_msi(dev->pdev))
512 dev_warn(dev->dev, "Enabling MSI failed!\n");527 dev_warn(dev->dev, "Enabling MSI failed!\n");
513 dev_priv->regmap = mdfld_regmap;528 dev_priv->regmap = mdfld_regmap;
529
530 /* Associate the GPIO lines with the DRM device */
531 mdfld_dsi_pipe_gpio_table.dev_id = dev_name(dev->dev);
532 gpiod_add_lookup_table(&mdfld_dsi_pipe_gpio_table);
533
514 return mid_chip_setup(dev);534 return mid_chip_setup(dev);
515}535}
516 536
drivers/gpu/drm/gma500/mdfld_dsi_dpi.c+1−1
@@ -955,7 +955,7 @@ struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, · 954 unmodified lines
955 955
956 /* panel hard-reset */956 /* panel hard-reset */
957 if (p_funcs->reset) {957 if (p_funcs->reset) {
958 ret = p_funcs->reset(pipe);958 ret = p_funcs->reset(dev, pipe);
959 if (ret) {959 if (ret) {
960 DRM_ERROR("Panel %d hard-reset failed\n", pipe);960 DRM_ERROR("Panel %d hard-reset failed\n", pipe);
961 return NULL;961 return NULL;
drivers/gpu/drm/gma500/mdfld_dsi_output.c+28−27
@@ -28,6 +28,7 @@ · 27 unmodified lines
28#include <linux/delay.h>28#include <linux/delay.h>
29#include <linux/moduleparam.h>29#include <linux/moduleparam.h>
30#include <linux/pm_runtime.h>30#include <linux/pm_runtime.h>
31#include <linux/gpio/consumer.h>
31 32
32#include <asm/intel_scu_ipc.h>33#include <asm/intel_scu_ipc.h>
33 34
@@ -366,7 +367,7 @@ static enum drm_mode_status mdfld_dsi_connector_mode_valid(struct drm_connector · 332 unmodified lines
366 /**367 /**
367 * FIXME: current DC has no fitting unit, reject any mode setting368 * FIXME: current DC has no fitting unit, reject any mode setting
368 * request369 * request
369 * Will figure out a way to do up-scaling(pannel fitting) later.370 * Will figure out a way to do up-scaling(panel fitting) later.
370 **/371 **/
371 if (fixed_mode) {372 if (fixed_mode) {
372 if (mode->hdisplay != fixed_mode->hdisplay)373 if (mode->hdisplay != fixed_mode->hdisplay)
@@ -432,42 +433,42 @@ static int mdfld_dsi_get_default_config(struct drm_device *dev, · 59 unmodified lines
432 return 0;433 return 0;
433}434}
434 435
435int mdfld_dsi_panel_reset(int pipe)436int mdfld_dsi_panel_reset(struct drm_device *ddev, int pipe)
436{437{
437 unsigned gpio;438 struct device *dev = ddev->dev;
438 int ret = 0;439 struct gpio_desc *gpiod;
439 440
441 /*
442 * Raise the GPIO reset line for the corresponding pipe to HIGH,
443 * this is probably because it is active low so this takes the
444 * respective pipe out of reset. (We have no code to put it back
445 * into reset in this driver.)
446 */
440 switch (pipe) {447 switch (pipe) {
441 case 0:448 case 0:
442 gpio = 128;449 gpiod = gpiod_get(dev, "dsi-pipe0-reset", GPIOD_OUT_HIGH);
450 if (IS_ERR(gpiod))
451 return PTR_ERR(gpiod);
443 break;452 break;
444 case 2:453 case 2:
445 gpio = 34;454 gpiod = gpiod_get(dev, "dsi-pipe2-reset", GPIOD_OUT_HIGH);
455 if (IS_ERR(gpiod))
456 return PTR_ERR(gpiod);
446 break;457 break;
447 default:458 default:
448 DRM_ERROR("Invalid output\n");459 DRM_DEV_ERROR(dev, "Invalid output pipe\n");
449 return -EINVAL;460 return -EINVAL;
450 }461 }
462 gpiod_put(gpiod);
451 463
452 ret = gpio_request(gpio, "gfx");464 /* Flush posted writes on the device */
453 if (ret) {465 gpiod = gpiod_get(dev, "dsi-pipe0-reset", GPIOD_ASIS);
454 DRM_ERROR("gpio_rqueset failed\n");466 if (IS_ERR(gpiod))
455 return ret;467 return PTR_ERR(gpiod);
456 }468 gpiod_get_value(gpiod);
457 469 gpiod_put(gpiod);
458 ret = gpio_direction_output(gpio, 1);
459 if (ret) {
460 DRM_ERROR("gpio_direction_output failed\n");
461 goto gpio_error;
462 }
463 470
464 gpio_get_value(128);471 return 0;
465
466gpio_error:
467 if (gpio_is_valid(gpio))
468 gpio_free(gpio);
469
470 return ret;
471}472}
472 473
473/*474/*
@@ -531,7 +532,7 @@ void mdfld_dsi_output_init(struct drm_device *dev, · 57 unmodified lines
531 dsi_config->connector = dsi_connector;532 dsi_config->connector = dsi_connector;
532 533
533 if (!dsi_config->fixed_mode) {534 if (!dsi_config->fixed_mode) {
534 DRM_ERROR("No pannel fixed mode was found\n");535 DRM_ERROR("No panel fixed mode was found\n");
535 goto dsi_init_err0;536 goto dsi_init_err0;
536 }537 }
537 538
drivers/gpu/drm/gma500/mdfld_dsi_output.h+1−1
@@ -372,6 +372,6 @@ extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config, · 371 unmodified lines
372 372
373extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,373extern int mdfld_dsi_get_power_mode(struct mdfld_dsi_config *dsi_config,
374 u32 *mode, bool hs);374 u32 *mode, bool hs);
375extern int mdfld_dsi_panel_reset(int pipe);375extern int mdfld_dsi_panel_reset(struct drm_device *dev, int pipe);
376 376
377#endif /*__MDFLD_DSI_OUTPUT_H__*/377#endif /*__MDFLD_DSI_OUTPUT_H__*/
drivers/gpu/drm/gma500/mdfld_output.h+1−1
@@ -54,7 +54,7 @@ struct panel_funcs { · 53 unmodified lines
54 const struct drm_encoder_helper_funcs *encoder_helper_funcs;54 const struct drm_encoder_helper_funcs *encoder_helper_funcs;
55 struct drm_display_mode * (*get_config_mode)(struct drm_device *);55 struct drm_display_mode * (*get_config_mode)(struct drm_device *);
56 int (*get_panel_info)(struct drm_device *, int, struct panel_info *);56 int (*get_panel_info)(struct drm_device *, int, struct panel_info *);
57 int (*reset)(int pipe);57 int (*reset)(struct drm_device *, int);
58 void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);58 void (*drv_ic_init)(struct mdfld_dsi_config *dsi_config, int pipe);
59};59};
60 60
drivers/gpu/drm/gma500/psb_intel_drv.h+0−1
@@ -13,7 +13,6 @@ · 12 unmodified lines
13#include <drm/drm_encoder.h>13#include <drm/drm_encoder.h>
14#include <drm/drm_probe_helper.h>14#include <drm/drm_probe_helper.h>
15#include <drm/drm_vblank.h>15#include <drm/drm_vblank.h>
16#include <linux/gpio.h>
17#include "gma_display.h"16#include "gma_display.h"
18 17
19/*18/*
drivers/gpu/drm/gma500/psb_intel_sdvo.c+1−1
@@ -125,7 +125,7 @@ struct psb_intel_sdvo { · 124 unmodified lines
125 bool is_lvds;125 bool is_lvds;
126 126
127 /**127 /**
128 * This is sdvo fixed pannel mode pointer128 * This is sdvo fixed panel mode pointer
129 */129 */
130 struct drm_display_mode *sdvo_lvds_fixed_mode;130 struct drm_display_mode *sdvo_lvds_fixed_mode;
131 131
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c+19−51
@@ -17,9 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_atomic_helper.h>17#include <drm/drm_atomic_helper.h>
18#include <drm/drm_fourcc.h>18#include <drm/drm_fourcc.h>
19#include <drm/drm_gem_vram_helper.h>19#include <drm/drm_gem_vram_helper.h>
20#include <drm/drm_plane_helper.h>
21#include <drm/drm_print.h>
22#include <drm/drm_probe_helper.h>
23#include <drm/drm_vblank.h>20#include <drm/drm_vblank.h>
24 21
25#include "hibmc_drm_drv.h"22#include "hibmc_drm_drv.h"
@@ -74,12 +71,12 @@ static int hibmc_plane_atomic_check(struct drm_plane *plane, · 48 unmodified lines
74 return PTR_ERR(crtc_state);71 return PTR_ERR(crtc_state);
75 72
76 if (src_w != state->crtc_w || src_h != state->crtc_h) {73 if (src_w != state->crtc_w || src_h != state->crtc_h) {
77 DRM_DEBUG_ATOMIC("scale not support\n");74 drm_dbg_atomic(plane->dev, "scale not support\n");
78 return -EINVAL;75 return -EINVAL;
79 }76 }
80 77
81 if (state->crtc_x < 0 || state->crtc_y < 0) {78 if (state->crtc_x < 0 || state->crtc_y < 0) {
82 DRM_DEBUG_ATOMIC("crtc_x/y of drm_plane state is invalid\n");79 drm_dbg_atomic(plane->dev, "crtc_x/y of drm_plane state is invalid\n");
83 return -EINVAL;80 return -EINVAL;
84 }81 }
85 82
@@ -90,12 +87,12 @@ static int hibmc_plane_atomic_check(struct drm_plane *plane, · 4 unmodified lines
90 crtc_state->adjusted_mode.hdisplay ||87 crtc_state->adjusted_mode.hdisplay ||
91 state->crtc_y + state->crtc_h >88 state->crtc_y + state->crtc_h >
92 crtc_state->adjusted_mode.vdisplay) {89 crtc_state->adjusted_mode.vdisplay) {
93 DRM_DEBUG_ATOMIC("visible portion of plane is invalid\n");90 drm_dbg_atomic(plane->dev, "visible portion of plane is invalid\n");
94 return -EINVAL;91 return -EINVAL;
95 }92 }
96 93
97 if (state->fb->pitches[0] % 128 != 0) {94 if (state->fb->pitches[0] % 128 != 0) {
98 DRM_DEBUG_ATOMIC("wrong stride with 128-byte aligned\n");95 drm_dbg_atomic(plane->dev, "wrong stride with 128-byte aligned\n");
99 return -EINVAL;96 return -EINVAL;
100 }97 }
101 return 0;98 return 0;
@@ -160,37 +157,6 @@ static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs = { · 58 unmodified lines
160 .atomic_update = hibmc_plane_atomic_update,157 .atomic_update = hibmc_plane_atomic_update,
161};158};
162 159
163static struct drm_plane *hibmc_plane_init(struct hibmc_drm_private *priv)
164{
165 struct drm_device *dev = priv->dev;
166 struct drm_plane *plane;
167 int ret = 0;
168
169 plane = devm_kzalloc(dev->dev, sizeof(*plane), GFP_KERNEL);
170 if (!plane) {
171 DRM_ERROR("failed to alloc memory when init plane\n");
172 return ERR_PTR(-ENOMEM);
173 }
174 /*
175 * plane init
176 * TODO: Now only support primary plane, overlay planes
177 * need to do.
178 */
179 ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
180 channel_formats1,
181 ARRAY_SIZE(channel_formats1),
182 NULL,
183 DRM_PLANE_TYPE_PRIMARY,
184 NULL);
185 if (ret) {
186 DRM_ERROR("failed to init plane: %d\n", ret);
187 return ERR_PTR(ret);
188 }
189
190 drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
191 return plane;
192}
193
194static void hibmc_crtc_dpms(struct drm_crtc *crtc, int dpms)160static void hibmc_crtc_dpms(struct drm_crtc *crtc, int dpms)
195{161{
196 struct hibmc_drm_private *priv = crtc->dev->dev_private;162 struct hibmc_drm_private *priv = crtc->dev->dev_private;
@@ -537,32 +503,34 @@ static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs = { · 340 unmodified lines
537int hibmc_de_init(struct hibmc_drm_private *priv)503int hibmc_de_init(struct hibmc_drm_private *priv)
538{504{
539 struct drm_device *dev = priv->dev;505 struct drm_device *dev = priv->dev;
540 struct drm_crtc *crtc;506 struct drm_crtc *crtc = &priv->crtc;
541 struct drm_plane *plane;507 struct drm_plane *plane = &priv->primary_plane;
542 int ret;508 int ret;
543 509
544 plane = hibmc_plane_init(priv);510 ret = drm_universal_plane_init(dev, plane, 1, &hibmc_plane_funcs,
545 if (IS_ERR(plane)) {511 channel_formats1,
546 DRM_ERROR("failed to create plane: %ld\n", PTR_ERR(plane));512 ARRAY_SIZE(channel_formats1),
547 return PTR_ERR(plane);513 NULL,
548 }514 DRM_PLANE_TYPE_PRIMARY,
515 NULL);
549 516
550 crtc = devm_kzalloc(dev->dev, sizeof(*crtc), GFP_KERNEL);517 if (ret) {
551 if (!crtc) {518 drm_err(dev, "failed to init plane: %d\n", ret);
552 DRM_ERROR("failed to alloc memory when init crtc\n");519 return ret;
553 return -ENOMEM;
554 }520 }
555 521
522 drm_plane_helper_add(plane, &hibmc_plane_helper_funcs);
523
556 ret = drm_crtc_init_with_planes(dev, crtc, plane,524 ret = drm_crtc_init_with_planes(dev, crtc, plane,
557 NULL, &hibmc_crtc_funcs, NULL);525 NULL, &hibmc_crtc_funcs, NULL);
558 if (ret) {526 if (ret) {
559 DRM_ERROR("failed to init crtc: %d\n", ret);527 drm_err(dev, "failed to init crtc: %d\n", ret);
560 return ret;528 return ret;
561 }529 }
562 530
563 ret = drm_mode_crtc_set_gamma_size(crtc, 256);531 ret = drm_mode_crtc_set_gamma_size(crtc, 256);
564 if (ret) {532 if (ret) {
565 DRM_ERROR("failed to set gamma size: %d\n", ret);533 drm_err(dev, "failed to set gamma size: %d\n", ret);
566 return ret;534 return ret;
567 }535 }
568 drm_crtc_helper_add(crtc, &hibmc_crtc_helper_funcs);536 drm_crtc_helper_add(crtc, &hibmc_crtc_helper_funcs);
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c+13−20
@@ -11,18 +11,14 @@ · 10 unmodified lines
11 * Jianhua Li <lijianhua@huawei.com>11 * Jianhua Li <lijianhua@huawei.com>
12 */12 */
13 13
14#include <linux/console.h>
15#include <linux/module.h>14#include <linux/module.h>
16#include <linux/pci.h>15#include <linux/pci.h>
17 16
18#include <drm/drm_atomic_helper.h>17#include <drm/drm_atomic_helper.h>
19#include <drm/drm_drv.h>18#include <drm/drm_drv.h>
20#include <drm/drm_fb_helper.h>
21#include <drm/drm_gem_vram_helper.h>19#include <drm/drm_gem_vram_helper.h>
22#include <drm/drm_irq.h>20#include <drm/drm_irq.h>
23#include <drm/drm_managed.h>21#include <drm/drm_managed.h>
24#include <drm/drm_print.h>
25#include <drm/drm_probe_helper.h>
26#include <drm/drm_vblank.h>22#include <drm/drm_vblank.h>
27 23
28#include "hibmc_drm_drv.h"24#include "hibmc_drm_drv.h"
@@ -102,13 +98,13 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv) · 73 unmodified lines
102 98
103 ret = hibmc_de_init(priv);99 ret = hibmc_de_init(priv);
104 if (ret) {100 if (ret) {
105 DRM_ERROR("failed to init de: %d\n", ret);101 drm_err(priv->dev, "failed to init de: %d\n", ret);
106 return ret;102 return ret;
107 }103 }
108 104
109 ret = hibmc_vdac_init(priv);105 ret = hibmc_vdac_init(priv);
110 if (ret) {106 if (ret) {
111 DRM_ERROR("failed to init vdac: %d\n", ret);107 drm_err(priv->dev, "failed to init vdac: %d\n", ret);
112 return ret;108 return ret;
113 }109 }
114 110
@@ -216,7 +212,7 @@ static int hibmc_hw_map(struct hibmc_drm_private *priv) · 101 unmodified lines
216 iosize = pci_resource_len(pdev, 1);212 iosize = pci_resource_len(pdev, 1);
217 priv->mmio = devm_ioremap(dev->dev, ioaddr, iosize);213 priv->mmio = devm_ioremap(dev->dev, ioaddr, iosize);
218 if (!priv->mmio) {214 if (!priv->mmio) {
219 DRM_ERROR("Cannot map mmio region\n");215 drm_err(dev, "Cannot map mmio region\n");
220 return -ENOMEM;216 return -ENOMEM;
221 }217 }
222 218
@@ -224,7 +220,7 @@ static int hibmc_hw_map(struct hibmc_drm_private *priv) · 1 unmodified line
224 size = pci_resource_len(pdev, 0);220 size = pci_resource_len(pdev, 0);
225 priv->fb_map = devm_ioremap(dev->dev, addr, size);221 priv->fb_map = devm_ioremap(dev->dev, addr, size);
226 if (!priv->fb_map) {222 if (!priv->fb_map) {
227 DRM_ERROR("Cannot map framebuffer\n");223 drm_err(dev, "Cannot map framebuffer\n");
228 return -ENOMEM;224 return -ENOMEM;
229 }225 }
230 priv->fb_base = addr;226 priv->fb_base = addr;
@@ -254,9 +250,8 @@ static int hibmc_unload(struct drm_device *dev) · 23 unmodified lines
254 250
255 if (dev->irq_enabled)251 if (dev->irq_enabled)
256 drm_irq_uninstall(dev);252 drm_irq_uninstall(dev);
257 if (priv->msi_enabled)
258 pci_disable_msi(dev->pdev);
259 253
254 pci_disable_msi(dev->pdev);
260 hibmc_kms_fini(priv);255 hibmc_kms_fini(priv);
261 hibmc_mm_fini(priv);256 hibmc_mm_fini(priv);
262 dev->dev_private = NULL;257 dev->dev_private = NULL;
@@ -270,7 +265,7 @@ static int hibmc_load(struct drm_device *dev) · 7 unmodified lines
270 265
271 priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);266 priv = drmm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
272 if (!priv) {267 if (!priv) {
273 DRM_ERROR("no memory to allocate for hibmc_drm_private\n");268 drm_err(dev, "no memory to allocate for hibmc_drm_private\n");
274 return -ENOMEM;269 return -ENOMEM;
275 }270 }
276 dev->dev_private = priv;271 dev->dev_private = priv;
@@ -290,19 +285,17 @@ static int hibmc_load(struct drm_device *dev) · 13 unmodified lines
290 285
291 ret = drm_vblank_init(dev, dev->mode_config.num_crtc);286 ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
292 if (ret) {287 if (ret) {
293 DRM_ERROR("failed to initialize vblank: %d\n", ret);288 drm_err(dev, "failed to initialize vblank: %d\n", ret);
294 goto err;289 goto err;
295 }290 }
296 291
297 priv->msi_enabled = 0;
298 ret = pci_enable_msi(dev->pdev);292 ret = pci_enable_msi(dev->pdev);
299 if (ret) {293 if (ret) {
300 DRM_WARN("enabling MSI failed: %d\n", ret);294 drm_warn(dev, "enabling MSI failed: %d\n", ret);
301 } else {295 } else {
302 priv->msi_enabled = 1;
303 ret = drm_irq_install(dev, dev->pdev->irq);296 ret = drm_irq_install(dev, dev->pdev->irq);
304 if (ret)297 if (ret)
305 DRM_WARN("install irq failed: %d\n", ret);298 drm_warn(dev, "install irq failed: %d\n", ret);
306 }299 }
307 300
308 /* reset all the states of crtc/plane/encoder/connector */301 /* reset all the states of crtc/plane/encoder/connector */
@@ -312,7 +305,7 @@ static int hibmc_load(struct drm_device *dev) · 3 unmodified lines
312 305
313err:306err:
314 hibmc_unload(dev);307 hibmc_unload(dev);
315 DRM_ERROR("failed to initialize drm driver: %d\n", ret);308 drm_err(dev, "failed to initialize drm driver: %d\n", ret);
316 return ret;309 return ret;
317}310}
318 311
@@ -338,19 +331,19 @@ static int hibmc_pci_probe(struct pci_dev *pdev, · 19 unmodified lines
338 331
339 ret = pci_enable_device(pdev);332 ret = pci_enable_device(pdev);
340 if (ret) {333 if (ret) {
341 DRM_ERROR("failed to enable pci device: %d\n", ret);334 drm_err(dev, "failed to enable pci device: %d\n", ret);
342 goto err_free;335 goto err_free;
343 }336 }
344 337
345 ret = hibmc_load(dev);338 ret = hibmc_load(dev);
346 if (ret) {339 if (ret) {
347 DRM_ERROR("failed to load hibmc: %d\n", ret);340 drm_err(dev, "failed to load hibmc: %d\n", ret);
348 goto err_disable;341 goto err_disable;
349 }342 }
350 343
351 ret = drm_dev_register(dev, 0);344 ret = drm_dev_register(dev, 0);
352 if (ret) {345 if (ret) {
353 DRM_ERROR("failed to register drv for userspace access: %d\n",346 drm_err(dev, "failed to register drv for userspace access: %d\n",
354 ret);347 ret);
355 goto err_unload;348 goto err_unload;
356 }349 }
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h+2−1
@@ -25,10 +25,11 @@ struct hibmc_drm_private { · 24 unmodified lines
25 void __iomem *fb_map;25 void __iomem *fb_map;
26 unsigned long fb_base;26 unsigned long fb_base;
27 unsigned long fb_size;27 unsigned long fb_size;
28 bool msi_enabled;
29 28
30 /* drm */29 /* drm */
31 struct drm_device *dev;30 struct drm_device *dev;
31 struct drm_plane primary_plane;
32 struct drm_crtc crtc;
32 struct drm_encoder encoder;33 struct drm_encoder encoder;
33 struct drm_connector connector;34 struct drm_connector connector;
34 bool mode_config_initialized;35 bool mode_config_initialized;
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c+2−4
@@ -11,10 +11,8 @@ · 10 unmodified lines
11 * Jianhua Li <lijianhua@huawei.com>11 * Jianhua Li <lijianhua@huawei.com>
12 */12 */
13 13
14#include <drm/drm_gem_vram_helper.h>
15#include <drm/drm_atomic_helper.h>14#include <drm/drm_atomic_helper.h>
16#include <drm/drm_probe_helper.h>15#include <drm/drm_probe_helper.h>
17#include <drm/drm_crtc_helper.h>
18#include <drm/drm_print.h>16#include <drm/drm_print.h>
19 17
20#include "hibmc_drm_drv.h"18#include "hibmc_drm_drv.h"
@@ -87,7 +85,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) · 66 unmodified lines
87 ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,85 ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
88 DRM_MODE_ENCODER_DAC, NULL);86 DRM_MODE_ENCODER_DAC, NULL);
89 if (ret) {87 if (ret) {
90 DRM_ERROR("failed to init encoder: %d\n", ret);88 drm_err(dev, "failed to init encoder: %d\n", ret);
91 return ret;89 return ret;
92 }90 }
93 91
@@ -96,7 +94,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) · 2 unmodified lines
96 ret = drm_connector_init(dev, connector, &hibmc_connector_funcs,94 ret = drm_connector_init(dev, connector, &hibmc_connector_funcs,
97 DRM_MODE_CONNECTOR_VGA);95 DRM_MODE_CONNECTOR_VGA);
98 if (ret) {96 if (ret) {
99 DRM_ERROR("failed to init connector: %d\n", ret);97 drm_err(dev, "failed to init connector: %d\n", ret);
100 return ret;98 return ret;
101 }99 }
102 drm_connector_helper_add(connector, &hibmc_connector_helper_funcs);100 drm_connector_helper_add(connector, &hibmc_connector_helper_funcs);
drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c+1−1
@@ -32,7 +32,7 @@ int hibmc_mm_init(struct hibmc_drm_private *hibmc) · 31 unmodified lines
32 hibmc->fb_size);32 hibmc->fb_size);
33 if (IS_ERR(vmm)) {33 if (IS_ERR(vmm)) {
34 ret = PTR_ERR(vmm);34 ret = PTR_ERR(vmm);
35 DRM_ERROR("Error initializing VRAM MM; %d\n", ret);35 drm_err(dev, "Error initializing VRAM MM; %d\n", ret);
36 return ret;36 return ret;
37 }37 }
38 38
drivers/gpu/drm/i915/display/intel_dp.c+8−0
@@ -6243,6 +6243,11 @@ out: · 6242 unmodified lines
6243 */6243 */
6244 intel_display_power_flush_work(dev_priv);6244 intel_display_power_flush_work(dev_priv);
6245 6245
6246 if (!intel_dp_is_edp(intel_dp))
6247 drm_dp_set_subconnector_property(connector,
6248 status,
6249 intel_dp->dpcd,
6250 intel_dp->downstream_ports);
6246 return status;6251 return status;
6247}6252}
6248 6253
@@ -7312,6 +7317,9 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect · 1063 unmodified lines
7312 struct drm_i915_private *dev_priv = to_i915(connector->dev);7317 struct drm_i915_private *dev_priv = to_i915(connector->dev);
7313 enum port port = dp_to_dig_port(intel_dp)->base.port;7318 enum port port = dp_to_dig_port(intel_dp)->base.port;
7314 7319
7320 if (!intel_dp_is_edp(intel_dp))
7321 drm_connector_attach_dp_subconnector_property(connector);
7322
7315 if (!IS_G4X(dev_priv) && port != PORT_A)7323 if (!IS_G4X(dev_priv) && port != PORT_A)
7316 intel_attach_force_audio_property(connector);7324 intel_attach_force_audio_property(connector);
7317 7325
drivers/gpu/drm/imx/imx-ldb.c+0−10
@@ -455,13 +455,6 @@ static int imx_ldb_register(struct drm_device *drm, · 454 unmodified lines
455 drm_connector_attach_encoder(&imx_ldb_ch->connector, encoder);455 drm_connector_attach_encoder(&imx_ldb_ch->connector, encoder);
456 }456 }
457 457
458 if (imx_ldb_ch->panel) {
459 ret = drm_panel_attach(imx_ldb_ch->panel,
460 &imx_ldb_ch->connector);
461 if (ret)
462 return ret;
463 }
464
465 return 0;458 return 0;
466}459}
467 460
@@ -702,9 +695,6 @@ static void imx_ldb_unbind(struct device *dev, struct device *master, · 234 unmodified lines
702 for (i = 0; i < 2; i++) {695 for (i = 0; i < 2; i++) {
703 struct imx_ldb_channel *channel = &imx_ldb->channel[i];696 struct imx_ldb_channel *channel = &imx_ldb->channel[i];
704 697
705 if (channel->panel)
706 drm_panel_detach(channel->panel);
707
708 kfree(channel->edid);698 kfree(channel->edid);
709 i2c_put_adapter(channel->ddc);699 i2c_put_adapter(channel->ddc);
710 }700 }
drivers/gpu/drm/imx/parallel-display.c+0−6
@@ -289,9 +289,6 @@ static int imx_pd_register(struct drm_device *drm, · 288 unmodified lines
289 DRM_MODE_CONNECTOR_DPI);289 DRM_MODE_CONNECTOR_DPI);
290 }290 }
291 291
292 if (imxpd->panel)
293 drm_panel_attach(imxpd->panel, &imxpd->connector);
294
295 if (imxpd->next_bridge) {292 if (imxpd->next_bridge) {
296 ret = drm_bridge_attach(encoder, imxpd->next_bridge,293 ret = drm_bridge_attach(encoder, imxpd->next_bridge,
297 &imxpd->bridge, 0);294 &imxpd->bridge, 0);
@@ -357,9 +354,6 @@ static void imx_pd_unbind(struct device *dev, struct device *master, · 59 unmodified lines
357{354{
358 struct imx_parallel_display *imxpd = dev_get_drvdata(dev);355 struct imx_parallel_display *imxpd = dev_get_drvdata(dev);
359 356
360 if (imxpd->panel)
361 drm_panel_detach(imxpd->panel);
362
363 kfree(imxpd->edid);357 kfree(imxpd->edid);
364}358}
365 359
drivers/gpu/drm/ingenic/ingenic-drm-drv.c+27−14
@@ -199,26 +199,20 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, · 198 unmodified lines
199{199{
200 struct ingenic_drm *priv = drm_crtc_get_priv(crtc);200 struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
201 struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL;201 struct drm_plane_state *f1_state, *f0_state, *ipu_state = NULL;
202 long rate;
203
204 if (!drm_atomic_crtc_needs_modeset(state))
205 return 0;
206
207 if (state->mode.hdisplay > priv->soc_info->max_width ||
208 state->mode.vdisplay > priv->soc_info->max_height)
209 return -EINVAL;
210 202
211 rate = clk_round_rate(priv->pix_clk,203 if (drm_atomic_crtc_needs_modeset(state) && priv->soc_info->has_osd) {
212 state->adjusted_mode.clock * 1000);
213 if (rate < 0)
214 return rate;
215
216 if (priv->soc_info->has_osd) {
217 f1_state = drm_atomic_get_plane_state(state->state, &priv->f1);204 f1_state = drm_atomic_get_plane_state(state->state, &priv->f1);
205 if (IS_ERR(f1_state))
206 return PTR_ERR(f1_state);
207
218 f0_state = drm_atomic_get_plane_state(state->state, &priv->f0);208 f0_state = drm_atomic_get_plane_state(state->state, &priv->f0);
209 if (IS_ERR(f0_state))
210 return PTR_ERR(f0_state);
219 211
220 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && priv->ipu_plane) {212 if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && priv->ipu_plane) {
221 ipu_state = drm_atomic_get_plane_state(state->state, priv->ipu_plane);213 ipu_state = drm_atomic_get_plane_state(state->state, priv->ipu_plane);
214 if (IS_ERR(ipu_state))
215 return PTR_ERR(ipu_state);
222 216
223 /* IPU and F1 planes cannot be enabled at the same time. */217 /* IPU and F1 planes cannot be enabled at the same time. */
224 if (f1_state->fb && ipu_state->fb) {218 if (f1_state->fb && ipu_state->fb) {
@@ -235,6 +229,24 @@ static int ingenic_drm_crtc_atomic_check(struct drm_crtc *crtc, · 10 unmodified lines
235 return 0;229 return 0;
236}230}
237 231
232static enum drm_mode_status
233ingenic_drm_crtc_mode_valid(struct drm_crtc *crtc, const struct drm_display_mode *mode)
234{
235 struct ingenic_drm *priv = drm_crtc_get_priv(crtc);
236 long rate;
237
238 if (mode->hdisplay > priv->soc_info->max_width)
239 return MODE_BAD_HVALUE;
240 if (mode->vdisplay > priv->soc_info->max_height)
241 return MODE_BAD_VVALUE;
242
243 rate = clk_round_rate(priv->pix_clk, mode->clock * 1000);
244 if (rate < 0)
245 return MODE_CLOCK_RANGE;
246
247 return MODE_OK;
248}
249
238static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc,250static void ingenic_drm_crtc_atomic_begin(struct drm_crtc *crtc,
239 struct drm_crtc_state *oldstate)251 struct drm_crtc_state *oldstate)
240{252{
@@ -648,6 +660,7 @@ static const struct drm_crtc_helper_funcs ingenic_drm_crtc_helper_funcs = { · 407 unmodified lines
648 .atomic_begin = ingenic_drm_crtc_atomic_begin,660 .atomic_begin = ingenic_drm_crtc_atomic_begin,
649 .atomic_flush = ingenic_drm_crtc_atomic_flush,661 .atomic_flush = ingenic_drm_crtc_atomic_flush,
650 .atomic_check = ingenic_drm_crtc_atomic_check,662 .atomic_check = ingenic_drm_crtc_atomic_check,
663 .mode_valid = ingenic_drm_crtc_mode_valid,
651};664};
652 665
653static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = {666static const struct drm_encoder_helper_funcs ingenic_drm_encoder_helper_funcs = {
drivers/gpu/drm/ingenic/ingenic-ipu.c+33−5
@@ -35,6 +35,7 @@ struct soc_info { · 34 unmodified lines
35 const u32 *formats;35 const u32 *formats;
36 size_t num_formats;36 size_t num_formats;
37 bool has_bicubic;37 bool has_bicubic;
38 bool manual_restart;
38 39
39 void (*set_coefs)(struct ingenic_ipu *ipu, unsigned int reg,40 void (*set_coefs)(struct ingenic_ipu *ipu, unsigned int reg,
40 unsigned int sharpness, bool downscale,41 unsigned int sharpness, bool downscale,
@@ -48,6 +49,7 @@ struct ingenic_ipu { · 7 unmodified lines
48 struct regmap *map;49 struct regmap *map;
49 struct clk *clk;50 struct clk *clk;
50 const struct soc_info *soc_info;51 const struct soc_info *soc_info;
52 bool clk_enabled;
51 53
52 unsigned int num_w, num_h, denom_w, denom_h;54 unsigned int num_w, num_h, denom_w, denom_h;
53 55
@@ -287,12 +289,23 @@ static void ingenic_ipu_plane_atomic_update(struct drm_plane *plane, · 233 unmodified lines
287 const struct drm_format_info *finfo;289 const struct drm_format_info *finfo;
288 u32 ctrl, stride = 0, coef_index = 0, format = 0;290 u32 ctrl, stride = 0, coef_index = 0, format = 0;
289 bool needs_modeset, upscaling_w, upscaling_h;291 bool needs_modeset, upscaling_w, upscaling_h;
292 int err;
290 293
291 if (!state || !state->fb)294 if (!state || !state->fb)
292 return;295 return;
293 296
294 finfo = drm_format_info(state->fb->format->format);297 finfo = drm_format_info(state->fb->format->format);
295 298
299 if (!ipu->clk_enabled) {
300 err = clk_enable(ipu->clk);
301 if (err) {
302 dev_err(ipu->dev, "Unable to enable clock: %d\n", err);
303 return;
304 }
305
306 ipu->clk_enabled = true;
307 }
308
296 /* Reset all the registers if needed */309 /* Reset all the registers if needed */
297 needs_modeset = drm_atomic_crtc_needs_modeset(state->crtc->state);310 needs_modeset = drm_atomic_crtc_needs_modeset(state->crtc->state);
298 if (needs_modeset) {311 if (needs_modeset) {
@@ -577,6 +590,11 @@ static void ingenic_ipu_plane_atomic_disable(struct drm_plane *plane, · 278 unmodified lines
577 regmap_clear_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CHIP_EN);590 regmap_clear_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_CHIP_EN);
578 591
579 ingenic_drm_plane_disable(ipu->master, plane);592 ingenic_drm_plane_disable(ipu->master, plane);
593
594 if (ipu->clk_enabled) {
595 clk_disable(ipu->clk);
596 ipu->clk_enabled = false;
597 }
580}598}
581 599
582static const struct drm_plane_helper_funcs ingenic_ipu_plane_helper_funcs = {600static const struct drm_plane_helper_funcs ingenic_ipu_plane_helper_funcs = {
@@ -645,7 +663,8 @@ static irqreturn_t ingenic_ipu_irq_handler(int irq, void *arg) · 62 unmodified lines
645 unsigned int dummy;663 unsigned int dummy;
646 664
647 /* dummy read allows CPU to reconfigure IPU */665 /* dummy read allows CPU to reconfigure IPU */
648 regmap_read(ipu->map, JZ_REG_IPU_STATUS, &dummy);666 if (ipu->soc_info->manual_restart)
667 regmap_read(ipu->map, JZ_REG_IPU_STATUS, &dummy);
649 668
650 /* ACK interrupt */669 /* ACK interrupt */
651 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0);670 regmap_write(ipu->map, JZ_REG_IPU_STATUS, 0);
@@ -656,7 +675,8 @@ static irqreturn_t ingenic_ipu_irq_handler(int irq, void *arg) · 4 unmodified lines
656 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v);675 regmap_write(ipu->map, JZ_REG_IPU_V_ADDR, ipu->addr_v);
657 676
658 /* Run IPU for the new frame */677 /* Run IPU for the new frame */
659 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RUN);678 if (ipu->soc_info->manual_restart)
679 regmap_set_bits(ipu->map, JZ_REG_IPU_CTRL, JZ_IPU_CTRL_RUN);
660 680
661 drm_crtc_handle_vblank(crtc);681 drm_crtc_handle_vblank(crtc);
662 682
@@ -758,9 +778,9 @@ static int ingenic_ipu_bind(struct device *dev, struct device *master, void *d) · 95 unmodified lines
758 drm_object_attach_property(&plane->base, ipu->sharpness_prop,778 drm_object_attach_property(&plane->base, ipu->sharpness_prop,
759 ipu->sharpness);779 ipu->sharpness);
760 780
761 err = clk_prepare_enable(ipu->clk);781 err = clk_prepare(ipu->clk);
762 if (err) {782 if (err) {
763 dev_err(dev, "Unable to enable clock\n");783 dev_err(dev, "Unable to prepare clock\n");
764 return err;784 return err;
765 }785 }
766 786
@@ -772,7 +792,7 @@ static void ingenic_ipu_unbind(struct device *dev, · 5 unmodified lines
772{792{
773 struct ingenic_ipu *ipu = dev_get_drvdata(dev);793 struct ingenic_ipu *ipu = dev_get_drvdata(dev);
774 794
775 clk_disable_unprepare(ipu->clk);795 clk_unprepare(ipu->clk);
776}796}
777 797
778static const struct component_ops ingenic_ipu_ops = {798static const struct component_ops ingenic_ipu_ops = {
@@ -792,10 +812,16 @@ static int ingenic_ipu_remove(struct platform_device *pdev) · 13 unmodified lines
792}812}
793 813
794static const u32 jz4725b_ipu_formats[] = {814static const u32 jz4725b_ipu_formats[] = {
815 /*
816 * While officially supported, packed YUV 4:2:2 formats can cause
817 * random hardware crashes on JZ4725B under certain circumstances.
818 * It seems to happen with some specific resize ratios.
819 * Until a proper workaround or fix is found, disable these formats.
795 DRM_FORMAT_YUYV,820 DRM_FORMAT_YUYV,
796 DRM_FORMAT_YVYU,821 DRM_FORMAT_YVYU,
797 DRM_FORMAT_UYVY,822 DRM_FORMAT_UYVY,
798 DRM_FORMAT_VYUY,823 DRM_FORMAT_VYUY,
824 */
799 DRM_FORMAT_YUV411,825 DRM_FORMAT_YUV411,
800 DRM_FORMAT_YUV420,826 DRM_FORMAT_YUV420,
801 DRM_FORMAT_YUV422,827 DRM_FORMAT_YUV422,
@@ -806,6 +832,7 @@ static const struct soc_info jz4725b_soc_info = { · 4 unmodified lines
806 .formats = jz4725b_ipu_formats,832 .formats = jz4725b_ipu_formats,
807 .num_formats = ARRAY_SIZE(jz4725b_ipu_formats),833 .num_formats = ARRAY_SIZE(jz4725b_ipu_formats),
808 .has_bicubic = false,834 .has_bicubic = false,
835 .manual_restart = true,
809 .set_coefs = jz4725b_set_coefs,836 .set_coefs = jz4725b_set_coefs,
810};837};
811 838
@@ -831,6 +858,7 @@ static const struct soc_info jz4760_soc_info = { · 19 unmodified lines
831 .formats = jz4760_ipu_formats,858 .formats = jz4760_ipu_formats,
832 .num_formats = ARRAY_SIZE(jz4760_ipu_formats),859 .num_formats = ARRAY_SIZE(jz4760_ipu_formats),
833 .has_bicubic = true,860 .has_bicubic = true,
861 .manual_restart = false,
834 .set_coefs = jz4760_set_coefs,862 .set_coefs = jz4760_set_coefs,
835};863};
836 864
drivers/gpu/drm/mcde/mcde_display.c+168−50
@@ -7,6 +7,7 @@ · 6 unmodified lines
7#include <linux/clk.h>7#include <linux/clk.h>
8#include <linux/delay.h>8#include <linux/delay.h>
9#include <linux/dma-buf.h>9#include <linux/dma-buf.h>
10#include <linux/regulator/consumer.h>
10 11
11#include <drm/drm_device.h>12#include <drm/drm_device.h>
12#include <drm/drm_fb_cma_helper.h>13#include <drm/drm_fb_cma_helper.h>
@@ -89,7 +90,7 @@ void mcde_display_irq(struct mcde *mcde) · 76 unmodified lines
89 * the update function is called, then we disable the90 * the update function is called, then we disable the
90 * flow on the channel once we get the TE IRQ.91 * flow on the channel once we get the TE IRQ.
91 */92 */
92 if (mcde->oneshot_mode) {93 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) {
93 spin_lock(&mcde->flow_lock);94 spin_lock(&mcde->flow_lock);
94 if (--mcde->flow_active == 0) {95 if (--mcde->flow_active == 0) {
95 dev_dbg(mcde->dev, "TE0 IRQ\n");96 dev_dbg(mcde->dev, "TE0 IRQ\n");
@@ -333,7 +334,7 @@ static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, · 237 unmodified lines
333 enum mcde_extsrc src,334 enum mcde_extsrc src,
334 enum mcde_channel ch,335 enum mcde_channel ch,
335 const struct drm_display_mode *mode,336 const struct drm_display_mode *mode,
336 u32 format)337 u32 format, int cpp)
337{338{
338 u32 val;339 u32 val;
339 u32 conf1;340 u32 conf1;
@@ -342,6 +343,7 @@ static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, · 2 unmodified lines
342 u32 ljinc;343 u32 ljinc;
343 u32 cr;344 u32 cr;
344 u32 comp;345 u32 comp;
346 u32 pixel_fetcher_watermark;
345 347
346 switch (ovl) {348 switch (ovl) {
347 case MCDE_OVERLAY_0:349 case MCDE_OVERLAY_0:
@@ -426,8 +428,33 @@ static void mcde_configure_overlay(struct mcde *mcde, enum mcde_overlay ovl, · 78 unmodified lines
426 format);428 format);
427 break;429 break;
428 }430 }
429 /* The default watermark level for overlay 0 is 48 */431
430 val |= 48 << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT;432 /*
433 * Pixel fetch watermark level is max 0x1FFF pixels.
434 * Two basic rules should be followed:
435 * 1. The value should be at least 256 bits.
436 * 2. The sum of all active overlays pixelfetch watermark level
437 * multiplied with bits per pixel, should be lower than the
438 * size of input_fifo_size in bits.
439 * 3. The value should be a multiple of a line (256 bits).
440 */
441 switch (cpp) {
442 case 2:
443 pixel_fetcher_watermark = 128;
444 break;
445 case 3:
446 pixel_fetcher_watermark = 96;
447 break;
448 case 4:
449 pixel_fetcher_watermark = 48;
450 break;
451 default:
452 pixel_fetcher_watermark = 48;
453 break;
454 }
455 dev_dbg(mcde->dev, "pixel fetcher watermark level %d pixels\n",
456 pixel_fetcher_watermark);
457 val |= pixel_fetcher_watermark << MCDE_OVLXCONF2_PIXELFETCHERWATERMARKLEVEL_SHIFT;
431 writel(val, mcde->regs + conf2);458 writel(val, mcde->regs + conf2);
432 459
433 /* Number of bytes to fetch per line */460 /* Number of bytes to fetch per line */
@@ -498,19 +525,47 @@ static void mcde_configure_channel(struct mcde *mcde, enum mcde_channel ch, · 64 unmodified lines
498 }525 }
499 526
500 /* Set up channel 0 sync (based on chnl_update_registers()) */527 /* Set up channel 0 sync (based on chnl_update_registers()) */
501 if (mcde->video_mode || mcde->te_sync)528 switch (mcde->flow_mode) {
529 case MCDE_COMMAND_ONESHOT_FLOW:
530 /* Oneshot is achieved with software sync */
531 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE
532 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
533 break;
534 case MCDE_COMMAND_TE_FLOW:
502 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE535 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
503 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;536 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
504 else537 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
505 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SOFTWARE538 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
539 break;
540 case MCDE_COMMAND_BTA_TE_FLOW:
541 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
542 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
543 /*
544 * TODO:
545 * The vendor driver uses the formatter as sync source
546 * for BTA TE mode. Test to use TE if you have a panel
547 * that uses this mode.
548 */
549 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER
550 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
551 break;
552 case MCDE_VIDEO_TE_FLOW:
553 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
506 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;554 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
507
508 if (mcde->te_sync)
509 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0555 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_TE0
510 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;556 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
511 else557 break;
558 case MCDE_VIDEO_FORMATTER_FLOW:
559 val = MCDE_CHNLXSYNCHMOD_SRC_SYNCH_HARDWARE
560 << MCDE_CHNLXSYNCHMOD_SRC_SYNCH_SHIFT;
512 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER561 val |= MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_FORMATTER
513 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;562 << MCDE_CHNLXSYNCHMOD_OUT_SYNCH_SRC_SHIFT;
563 break;
564 default:
565 dev_err(mcde->dev, "unknown flow mode %d\n",
566 mcde->flow_mode);
567 break;
568 }
514 569
515 writel(val, mcde->regs + sync);570 writel(val, mcde->regs + sync);
516 571
@@ -825,6 +880,14 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 308 unmodified lines
825 u32 formatter_frame;880 u32 formatter_frame;
826 u32 pkt_div;881 u32 pkt_div;
827 u32 val;882 u32 val;
883 int ret;
884
885 /* This powers up the entire MCDE block and the DSI hardware */
886 ret = regulator_enable(mcde->epod);
887 if (ret) {
888 dev_err(drm->dev, "can't re-enable EPOD regulator\n");
889 return;
890 }
828 891
829 dev_info(drm->dev, "enable MCDE, %d x %d format %s\n",892 dev_info(drm->dev, "enable MCDE, %d x %d format %s\n",
830 mode->hdisplay, mode->vdisplay,893 mode->hdisplay, mode->vdisplay,
@@ -835,6 +898,26 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 4 unmodified lines
835 return;898 return;
836 }899 }
837 900
901 /* Set up the main control, watermark level at 7 */
902 val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT;
903 /* 24 bits DPI: connect LSB Ch B to D[0:7] */
904 val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT;
905 /* TV out: connect LSB Ch B to D[8:15] */
906 val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT;
907 /* Don't care about this muxing */
908 val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT;
909 /* 24 bits DPI: connect MID Ch B to D[24:31] */
910 val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT;
911 /* 5: 24 bits DPI: connect MSB Ch B to D[32:39] */
912 val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT;
913 /* Syncmux bits zero: DPI channel A and B on output pins A and B resp */
914 writel(val, mcde->regs + MCDE_CONF0);
915
916 /* Clear any pending interrupts */
917 mcde_display_disable_irqs(mcde);
918 writel(0, mcde->regs + MCDE_IMSCERR);
919 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR);
920
838 dev_info(drm->dev, "output in %s mode, format %dbpp\n",921 dev_info(drm->dev, "output in %s mode, format %dbpp\n",
839 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ?922 (mcde->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ?
840 "VIDEO" : "CMD",923 "VIDEO" : "CMD",
@@ -904,7 +987,7 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 63 unmodified lines
904 * channel 0987 * channel 0
905 */988 */
906 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0,989 mcde_configure_overlay(mcde, MCDE_OVERLAY_0, MCDE_EXTSRC_0,
907 MCDE_CHANNEL_0, mode, format);990 MCDE_CHANNEL_0, mode, format, cpp);
908 991
909 /*992 /*
910 * Configure pixel-per-line and line-per-frame for channel 0 and then993 * Configure pixel-per-line and line-per-frame for channel 0 and then
@@ -916,11 +999,25 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 5 unmodified lines
916 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0,999 mcde_configure_fifo(mcde, MCDE_FIFO_A, MCDE_DSI_FORMATTER_0,
917 fifo_wtrmrk);1000 fifo_wtrmrk);
918 1001
1002 /*
1003 * This brings up the DSI bridge which is tightly connected
1004 * to the MCDE DSI formatter.
1005 *
1006 * FIXME: if we want to use another formatter, such as DPI,
1007 * we need to be more elaborate here and select the appropriate
1008 * bridge.
1009 */
1010 mcde_dsi_enable(mcde->bridge);
1011
919 /* Configure the DSI formatter 0 for the DSI panel output */1012 /* Configure the DSI formatter 0 for the DSI panel output */
920 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0,1013 mcde_configure_dsi_formatter(mcde, MCDE_DSI_FORMATTER_0,
921 formatter_frame, pkt_size);1014 formatter_frame, pkt_size);
922 1015
923 if (mcde->te_sync) {1016 switch (mcde->flow_mode) {
1017 case MCDE_COMMAND_TE_FLOW:
1018 case MCDE_COMMAND_BTA_TE_FLOW:
1019 case MCDE_VIDEO_TE_FLOW:
1020 /* We are using TE in some comination */
924 if (mode->flags & DRM_MODE_FLAG_NVSYNC)1021 if (mode->flags & DRM_MODE_FLAG_NVSYNC)
925 val = MCDE_VSCRC_VSPOL;1022 val = MCDE_VSCRC_VSPOL;
926 else1023 else
@@ -930,16 +1027,31 @@ static void mcde_display_enable(struct drm_simple_display_pipe *pipe, · 3 unmodified lines
930 val = readl(mcde->regs + MCDE_CRC);1027 val = readl(mcde->regs + MCDE_CRC);
931 val |= MCDE_CRC_SYCEN0;1028 val |= MCDE_CRC_SYCEN0;
932 writel(val, mcde->regs + MCDE_CRC);1029 writel(val, mcde->regs + MCDE_CRC);
1030 break;
1031 default:
1032 /* No TE capture */
1033 break;
933 }1034 }
934 1035
935 drm_crtc_vblank_on(crtc);1036 drm_crtc_vblank_on(crtc);
936 1037
937 if (mcde->video_mode)1038 /*
938 /*1039 * If we're using oneshot mode we don't start the flow
939 * Keep FIFO permanently enabled in video mode,1040 * until each time the display is given an update, and
940 * otherwise MCDE will stop feeding data to the panel.1041 * then we disable it immediately after. For all other
941 */1042 * modes (command or video) we start the FIFO flow
1043 * right here. This is necessary for the hardware to
1044 * behave right.
1045 */
1046 if (mcde->flow_mode != MCDE_COMMAND_ONESHOT_FLOW) {
942 mcde_enable_fifo(mcde, MCDE_FIFO_A);1047 mcde_enable_fifo(mcde, MCDE_FIFO_A);
1048 dev_dbg(mcde->dev, "started MCDE video FIFO flow\n");
1049 }
1050
1051 /* Enable MCDE with automatic clock gating */
1052 val = readl(mcde->regs + MCDE_CR);
1053 val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN;
1054 writel(val, mcde->regs + MCDE_CR);
943 1055
944 dev_info(drm->dev, "MCDE display is enabled\n");1056 dev_info(drm->dev, "MCDE display is enabled\n");
945}1057}
@@ -950,12 +1062,16 @@ static void mcde_display_disable(struct drm_simple_display_pipe *pipe) · 4 unmodified lines
950 struct drm_device *drm = crtc->dev;1062 struct drm_device *drm = crtc->dev;
951 struct mcde *mcde = to_mcde(drm);1063 struct mcde *mcde = to_mcde(drm);
952 struct drm_pending_vblank_event *event;1064 struct drm_pending_vblank_event *event;
1065 int ret;
953 1066
954 drm_crtc_vblank_off(crtc);1067 drm_crtc_vblank_off(crtc);
955 1068
956 /* Disable FIFO A flow */1069 /* Disable FIFO A flow */
957 mcde_disable_fifo(mcde, MCDE_FIFO_A, true);1070 mcde_disable_fifo(mcde, MCDE_FIFO_A, true);
958 1071
1072 /* This disables the DSI bridge */
1073 mcde_dsi_disable(mcde->bridge);
1074
959 event = crtc->state->event;1075 event = crtc->state->event;
960 if (event) {1076 if (event) {
961 crtc->state->event = NULL;1077 crtc->state->event = NULL;
@@ -965,43 +1081,47 @@ static void mcde_display_disable(struct drm_simple_display_pipe *pipe) · 3 unmodified lines
965 spin_unlock_irq(&crtc->dev->event_lock);1081 spin_unlock_irq(&crtc->dev->event_lock);
966 }1082 }
967 1083
1084 ret = regulator_disable(mcde->epod);
1085 if (ret)
1086 dev_err(drm->dev, "can't disable EPOD regulator\n");
1087 /* Make sure we are powered down (before we may power up again) */
1088 usleep_range(50000, 70000);
1089
968 dev_info(drm->dev, "MCDE display is disabled\n");1090 dev_info(drm->dev, "MCDE display is disabled\n");
969}1091}
970 1092
971static void mcde_display_send_one_frame(struct mcde *mcde)1093static void mcde_start_flow(struct mcde *mcde)
972{1094{
973 /* Request a TE ACK */1095 /* Request a TE ACK only in TE+BTA mode */
974 if (mcde->te_sync)1096 if (mcde->flow_mode == MCDE_COMMAND_BTA_TE_FLOW)
975 mcde_dsi_te_request(mcde->mdsi);1097 mcde_dsi_te_request(mcde->mdsi);
976 1098
977 /* Enable FIFO A flow */1099 /* Enable FIFO A flow */
978 mcde_enable_fifo(mcde, MCDE_FIFO_A);1100 mcde_enable_fifo(mcde, MCDE_FIFO_A);
979 1101
980 if (mcde->te_sync) {1102 /*
1103 * If oneshot mode is enabled, the flow will be disabled
1104 * when the TE0 IRQ arrives in the interrupt handler. Otherwise
1105 * updates are continuously streamed to the display after this
1106 * point.
1107 */
1108
1109 if (mcde->flow_mode == MCDE_COMMAND_ONESHOT_FLOW) {
1110 /* Trigger a software sync out on channel 0 */
1111 writel(MCDE_CHNLXSYNCHSW_SW_TRIG,
1112 mcde->regs + MCDE_CHNL0SYNCHSW);
1113
981 /*1114 /*
982 * If oneshot mode is enabled, the flow will be disabled1115 * Disable FIFO A flow again: since we are using TE sync we
983 * when the TE0 IRQ arrives in the interrupt handler. Otherwise1116 * need to wait for the FIFO to drain before we continue
984 * updates are continuously streamed to the display after this1117 * so repeated calls to this function will not cause a mess
985 * point.1118 * in the hardware by pushing updates will updates are going
1119 * on already.
986 */1120 */
987 dev_dbg(mcde->dev, "sent TE0 framebuffer update\n");1121 mcde_disable_fifo(mcde, MCDE_FIFO_A, true);
988 return;
989 }1122 }
990 1123
991 /* Trigger a software sync out on channel 0 */1124 dev_dbg(mcde->dev, "started MCDE FIFO flow\n");
992 writel(MCDE_CHNLXSYNCHSW_SW_TRIG,
993 mcde->regs + MCDE_CHNL0SYNCHSW);
994
995 /*
996 * Disable FIFO A flow again: since we are using TE sync we
997 * need to wait for the FIFO to drain before we continue
998 * so repeated calls to this function will not cause a mess
999 * in the hardware by pushing updates will updates are going
1000 * on already.
1001 */
1002 mcde_disable_fifo(mcde, MCDE_FIFO_A, true);
1003
1004 dev_dbg(mcde->dev, "sent SW framebuffer update\n");
1005}1125}
1006 1126
1007static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address)1127static void mcde_set_extsrc(struct mcde *mcde, u32 buffer_address)
@@ -1060,15 +1180,13 @@ static void mcde_display_update(struct drm_simple_display_pipe *pipe, · 52 unmodified lines
1060 */1180 */
1061 if (fb) {1181 if (fb) {
1062 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0));1182 mcde_set_extsrc(mcde, drm_fb_cma_get_gem_addr(fb, pstate, 0));
1063 if (!mcde->video_mode) {1183 dev_info_once(mcde->dev, "first update of display contents\n");
1064 /*1184 /*
1065 * Send a single frame using software sync if the flow1185 * Usually the flow is already active, unless we are in
1066 * is not active yet.1186 * oneshot mode, then we need to kick the flow right here.
1067 */1187 */
1068 if (mcde->flow_active == 0)1188 if (mcde->flow_active == 0)
1069 mcde_display_send_one_frame(mcde);1189 mcde_start_flow(mcde);
1070 }
1071 dev_info_once(mcde->dev, "sent first display update\n");
1072 } else {1190 } else {
1073 /*1191 /*
1074 * If an update is receieved before the MCDE is enabled1192 * If an update is receieved before the MCDE is enabled
drivers/gpu/drm/mcde/mcde_drm.h+64−3
@@ -9,6 +9,61 @@ · 8 unmodified lines
9#ifndef _MCDE_DRM_H_9#ifndef _MCDE_DRM_H_
10#define _MCDE_DRM_H_10#define _MCDE_DRM_H_
11 11
12/* Shared basic registers */
13#define MCDE_CR 0x00000000
14#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0
15#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F
16#define MCDE_CR_IFIFOCTRLEN BIT(15)
17#define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16)
18#define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17)
19#define MCDE_CR_AUTOCLKG_EN BIT(30)
20#define MCDE_CR_MCDEEN BIT(31)
21
22#define MCDE_CONF0 0x00000004
23#define MCDE_CONF0_SYNCMUX0 BIT(0)
24#define MCDE_CONF0_SYNCMUX1 BIT(1)
25#define MCDE_CONF0_SYNCMUX2 BIT(2)
26#define MCDE_CONF0_SYNCMUX3 BIT(3)
27#define MCDE_CONF0_SYNCMUX4 BIT(4)
28#define MCDE_CONF0_SYNCMUX5 BIT(5)
29#define MCDE_CONF0_SYNCMUX6 BIT(6)
30#define MCDE_CONF0_SYNCMUX7 BIT(7)
31#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT 12
32#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_MASK 0x00007000
33#define MCDE_CONF0_OUTMUX0_SHIFT 16
34#define MCDE_CONF0_OUTMUX0_MASK 0x00070000
35#define MCDE_CONF0_OUTMUX1_SHIFT 19
36#define MCDE_CONF0_OUTMUX1_MASK 0x00380000
37#define MCDE_CONF0_OUTMUX2_SHIFT 22
38#define MCDE_CONF0_OUTMUX2_MASK 0x01C00000
39#define MCDE_CONF0_OUTMUX3_SHIFT 25
40#define MCDE_CONF0_OUTMUX3_MASK 0x0E000000
41#define MCDE_CONF0_OUTMUX4_SHIFT 28
42#define MCDE_CONF0_OUTMUX4_MASK 0x70000000
43
44#define MCDE_SSP 0x00000008
45#define MCDE_AIS 0x00000100
46#define MCDE_IMSCERR 0x00000110
47#define MCDE_RISERR 0x00000120
48#define MCDE_MISERR 0x00000130
49#define MCDE_SISERR 0x00000140
50
51enum mcde_flow_mode {
52 /* One-shot mode: flow stops after one frame */
53 MCDE_COMMAND_ONESHOT_FLOW,
54 /* Command mode with tearing effect (TE) IRQ sync */
55 MCDE_COMMAND_TE_FLOW,
56 /*
57 * Command mode with bus turn-around (BTA) and tearing effect
58 * (TE) IRQ sync.
59 */
60 MCDE_COMMAND_BTA_TE_FLOW,
61 /* Video mode with tearing effect (TE) sync IRQ */
62 MCDE_VIDEO_TE_FLOW,
63 /* Video mode with the formatter itself as sync source */
64 MCDE_VIDEO_FORMATTER_FLOW,
65};
66
12struct mcde {67struct mcde {
13 struct drm_device drm;68 struct drm_device drm;
14 struct device *dev;69 struct device *dev;
@@ -18,9 +73,7 @@ struct mcde { · 3 unmodified lines
18 struct drm_simple_display_pipe pipe;73 struct drm_simple_display_pipe pipe;
19 struct mipi_dsi_device *mdsi;74 struct mipi_dsi_device *mdsi;
20 s16 stride;75 s16 stride;
21 bool te_sync;76 enum mcde_flow_mode flow_mode;
22 bool video_mode;
23 bool oneshot_mode;
24 unsigned int flow_active;77 unsigned int flow_active;
25 spinlock_t flow_lock; /* Locks the channel flow control */78 spinlock_t flow_lock; /* Locks the channel flow control */
26 79
@@ -36,8 +89,16 @@ struct mcde { · 9 unmodified lines
36 89
37#define to_mcde(dev) container_of(dev, struct mcde, drm)90#define to_mcde(dev) container_of(dev, struct mcde, drm)
38 91
92static inline bool mcde_flow_is_video(struct mcde *mcde)
93{
94 return (mcde->flow_mode == MCDE_VIDEO_TE_FLOW ||
95 mcde->flow_mode == MCDE_VIDEO_FORMATTER_FLOW);
96}
97
39bool mcde_dsi_irq(struct mipi_dsi_device *mdsi);98bool mcde_dsi_irq(struct mipi_dsi_device *mdsi);
40void mcde_dsi_te_request(struct mipi_dsi_device *mdsi);99void mcde_dsi_te_request(struct mipi_dsi_device *mdsi);
100void mcde_dsi_enable(struct drm_bridge *bridge);
101void mcde_dsi_disable(struct drm_bridge *bridge);
41extern struct platform_driver mcde_dsi_driver;102extern struct platform_driver mcde_dsi_driver;
42 103
43void mcde_display_irq(struct mcde *mcde);104void mcde_display_irq(struct mcde *mcde);
drivers/gpu/drm/mcde/mcde_drv.c+18−63
@@ -63,6 +63,7 @@ · 62 unmodified lines
63#include <linux/platform_device.h>63#include <linux/platform_device.h>
64#include <linux/regulator/consumer.h>64#include <linux/regulator/consumer.h>
65#include <linux/slab.h>65#include <linux/slab.h>
66#include <linux/delay.h>
66 67
67#include <drm/drm_atomic_helper.h>68#include <drm/drm_atomic_helper.h>
68#include <drm/drm_bridge.h>69#include <drm/drm_bridge.h>
@@ -82,44 +83,6 @@ · 13 unmodified lines
82 83
83#define DRIVER_DESC "DRM module for MCDE"84#define DRIVER_DESC "DRM module for MCDE"
84 85
85#define MCDE_CR 0x00000000
86#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_SHIFT 0
87#define MCDE_CR_IFIFOEMPTYLINECOUNT_V422_MASK 0x0000003F
88#define MCDE_CR_IFIFOCTRLEN BIT(15)
89#define MCDE_CR_UFRECOVERY_MODE_V422 BIT(16)
90#define MCDE_CR_WRAP_MODE_V422_SHIFT BIT(17)
91#define MCDE_CR_AUTOCLKG_EN BIT(30)
92#define MCDE_CR_MCDEEN BIT(31)
93
94#define MCDE_CONF0 0x00000004
95#define MCDE_CONF0_SYNCMUX0 BIT(0)
96#define MCDE_CONF0_SYNCMUX1 BIT(1)
97#define MCDE_CONF0_SYNCMUX2 BIT(2)
98#define MCDE_CONF0_SYNCMUX3 BIT(3)
99#define MCDE_CONF0_SYNCMUX4 BIT(4)
100#define MCDE_CONF0_SYNCMUX5 BIT(5)
101#define MCDE_CONF0_SYNCMUX6 BIT(6)
102#define MCDE_CONF0_SYNCMUX7 BIT(7)
103#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT 12
104#define MCDE_CONF0_IFIFOCTRLWTRMRKLVL_MASK 0x00007000
105#define MCDE_CONF0_OUTMUX0_SHIFT 16
106#define MCDE_CONF0_OUTMUX0_MASK 0x00070000
107#define MCDE_CONF0_OUTMUX1_SHIFT 19
108#define MCDE_CONF0_OUTMUX1_MASK 0x00380000
109#define MCDE_CONF0_OUTMUX2_SHIFT 22
110#define MCDE_CONF0_OUTMUX2_MASK 0x01C00000
111#define MCDE_CONF0_OUTMUX3_SHIFT 25
112#define MCDE_CONF0_OUTMUX3_MASK 0x0E000000
113#define MCDE_CONF0_OUTMUX4_SHIFT 28
114#define MCDE_CONF0_OUTMUX4_MASK 0x70000000
115
116#define MCDE_SSP 0x00000008
117#define MCDE_AIS 0x00000100
118#define MCDE_IMSCERR 0x00000110
119#define MCDE_RISERR 0x00000120
120#define MCDE_MISERR 0x00000130
121#define MCDE_SISERR 0x00000140
122
123#define MCDE_PID 0x000001FC86#define MCDE_PID 0x000001FC
124#define MCDE_PID_METALFIX_VERSION_SHIFT 087#define MCDE_PID_METALFIX_VERSION_SHIFT 0
125#define MCDE_PID_METALFIX_VERSION_MASK 0x000000FF88#define MCDE_PID_METALFIX_VERSION_MASK 0x000000FF
@@ -293,7 +256,6 @@ static int mcde_probe(struct platform_device *pdev) · 167 unmodified lines
293 struct component_match *match = NULL;256 struct component_match *match = NULL;
294 struct resource *res;257 struct resource *res;
295 u32 pid;258 u32 pid;
296 u32 val;
297 int irq;259 int irq;
298 int ret;260 int ret;
299 int i;261 int i;
@@ -305,9 +267,6 @@ static int mcde_probe(struct platform_device *pdev) · 5 unmodified lines
305 mcde->dev = dev;267 mcde->dev = dev;
306 platform_set_drvdata(pdev, drm);268 platform_set_drvdata(pdev, drm);
307 269
308 /* Enable continuous updates: this is what Linux' framebuffer expects */
309 mcde->oneshot_mode = false;
310
311 /* First obtain and turn on the main power */270 /* First obtain and turn on the main power */
312 mcde->epod = devm_regulator_get(dev, "epod");271 mcde->epod = devm_regulator_get(dev, "epod");
313 if (IS_ERR(mcde->epod)) {272 if (IS_ERR(mcde->epod)) {
@@ -405,27 +364,7 @@ static int mcde_probe(struct platform_device *pdev) · 91 unmodified lines
405 goto clk_disable;364 goto clk_disable;
406 }365 }
407 366
408 /* Set up the main control, watermark level at 7 */367 /* Disable and clear any pending interrupts */
409 val = 7 << MCDE_CONF0_IFIFOCTRLWTRMRKLVL_SHIFT;
410 /* 24 bits DPI: connect LSB Ch B to D[0:7] */
411 val |= 3 << MCDE_CONF0_OUTMUX0_SHIFT;
412 /* TV out: connect LSB Ch B to D[8:15] */
413 val |= 3 << MCDE_CONF0_OUTMUX1_SHIFT;
414 /* Don't care about this muxing */
415 val |= 0 << MCDE_CONF0_OUTMUX2_SHIFT;
416 /* 24 bits DPI: connect MID Ch B to D[24:31] */
417 val |= 4 << MCDE_CONF0_OUTMUX3_SHIFT;
418 /* 5: 24 bits DPI: connect MSB Ch B to D[32:39] */
419 val |= 5 << MCDE_CONF0_OUTMUX4_SHIFT;
420 /* Syncmux bits zero: DPI channel A and B on output pins A and B resp */
421 writel(val, mcde->regs + MCDE_CONF0);
422
423 /* Enable automatic clock gating */
424 val = readl(mcde->regs + MCDE_CR);
425 val |= MCDE_CR_MCDEEN | MCDE_CR_AUTOCLKG_EN;
426 writel(val, mcde->regs + MCDE_CR);
427
428 /* Clear any pending interrupts */
429 mcde_display_disable_irqs(mcde);368 mcde_display_disable_irqs(mcde);
430 writel(0, mcde->regs + MCDE_IMSCERR);369 writel(0, mcde->regs + MCDE_IMSCERR);
431 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR);370 writel(0xFFFFFFFF, mcde->regs + MCDE_RISERR);
@@ -455,12 +394,28 @@ static int mcde_probe(struct platform_device *pdev) · 23 unmodified lines
455 ret = PTR_ERR(match);394 ret = PTR_ERR(match);
456 goto clk_disable;395 goto clk_disable;
457 }396 }
397
398 /*
399 * Perform an invasive reset of the MCDE and all blocks by
400 * cutting the power to the subsystem, then bring it back up
401 * later when we enable the display as a result of
402 * component_master_add_with_match().
403 */
404 ret = regulator_disable(mcde->epod);
405 if (ret) {
406 dev_err(dev, "can't disable EPOD regulator\n");
407 return ret;
408 }
409 /* Wait 50 ms so we are sure we cut the power */
410 usleep_range(50000, 70000);
411
458 ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops,412 ret = component_master_add_with_match(&pdev->dev, &mcde_drm_comp_ops,
459 match);413 match);
460 if (ret) {414 if (ret) {
461 dev_err(dev, "failed to add component master\n");415 dev_err(dev, "failed to add component master\n");
462 goto clk_disable;416 goto clk_disable;
463 }417 }
418
464 return 0;419 return 0;
465 420
466clk_disable:421clk_disable:
drivers/gpu/drm/mcde/mcde_dsi.c+160−116
@@ -43,6 +43,7 @@ struct mcde_dsi { · 42 unmodified lines
43 struct drm_bridge *bridge_out;43 struct drm_bridge *bridge_out;
44 struct mipi_dsi_host dsi_host;44 struct mipi_dsi_host dsi_host;
45 struct mipi_dsi_device *mdsi;45 struct mipi_dsi_device *mdsi;
46 const struct drm_display_mode *mode;
46 struct clk *hs_clk;47 struct clk *hs_clk;
47 struct clk *lp_clk;48 struct clk *lp_clk;
48 unsigned long hs_freq;49 unsigned long hs_freq;
@@ -148,9 +149,22 @@ static void mcde_dsi_attach_to_mcde(struct mcde_dsi *d) · 99 unmodified lines
148{149{
149 d->mcde->mdsi = d->mdsi;150 d->mcde->mdsi = d->mdsi;
150 151
151 d->mcde->video_mode = !!(d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO);152 /*
152 /* Enable use of the TE signal for all command mode panels */153 * Select the way the DSI data flow is pushing to the display:
153 d->mcde->te_sync = !d->mcde->video_mode;154 * currently we just support video or command mode depending
155 * on the type of display. Video mode defaults to using the
156 * formatter itself for synchronization (stateless video panel).
157 *
158 * FIXME: add flags to struct mipi_dsi_device .flags to indicate
159 * displays that require BTA (bus turn around) so we can handle
160 * such displays as well. Figure out how to properly handle
161 * single frame on-demand updates with DRM for command mode
162 * displays (MCDE_COMMAND_ONESHOT_FLOW).
163 */
164 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)
165 d->mcde->flow_mode = MCDE_VIDEO_FORMATTER_FLOW;
166 else
167 d->mcde->flow_mode = MCDE_COMMAND_TE_FLOW;
154}168}
155 169
156static int mcde_dsi_host_attach(struct mipi_dsi_host *host,170static int mcde_dsi_host_attach(struct mipi_dsi_host *host,
@@ -194,79 +208,16 @@ static int mcde_dsi_host_detach(struct mipi_dsi_host *host, · 37 unmodified lines
194 (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \208 (type == MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM) || \
195 (type == MIPI_DSI_DCS_READ))209 (type == MIPI_DSI_DCS_READ))
196 210
197static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,211static int mcde_dsi_execute_transfer(struct mcde_dsi *d,
198 const struct mipi_dsi_msg *msg)212 const struct mipi_dsi_msg *msg)
199{213{
200 struct mcde_dsi *d = host_to_mcde_dsi(host);
201 const u32 loop_delay_us = 10; /* us */214 const u32 loop_delay_us = 10; /* us */
202 const u8 *tx = msg->tx_buf;
203 u32 loop_counter;215 u32 loop_counter;
204 size_t txlen = msg->tx_len;216 size_t txlen = msg->tx_len;
205 size_t rxlen = msg->rx_len;217 size_t rxlen = msg->rx_len;
218 int i;
206 u32 val;219 u32 val;
207 int ret;220 int ret;
208 int i;
209
210 if (txlen > 16) {
211 dev_err(d->dev,
212 "dunno how to write more than 16 bytes yet\n");
213 return -EIO;
214 }
215 if (rxlen > 4) {
216 dev_err(d->dev,
217 "dunno how to read more than 4 bytes yet\n");
218 return -EIO;
219 }
220
221 dev_dbg(d->dev,
222 "message to channel %d, write %zd bytes read %zd bytes\n",
223 msg->channel, txlen, rxlen);
224
225 /* Command "nature" */
226 if (MCDE_DSI_HOST_IS_READ(msg->type))
227 /* MCTL_MAIN_DATA_CTL already set up */
228 val = DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_READ;
229 else
230 val = DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_WRITE;
231 /*
232 * More than 2 bytes will not fit in a single packet, so it's
233 * time to set the "long not short" bit. One byte is used by
234 * the MIPI DCS command leaving just one byte for the payload
235 * in a short package.
236 */
237 if (mipi_dsi_packet_format_is_long(msg->type))
238 val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LONGNOTSHORT;
239 val |= 0 << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_ID_SHIFT;
240 val |= txlen << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_SIZE_SHIFT;
241 val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LP_EN;
242 val |= msg->type << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHIFT;
243 writel(val, d->regs + DSI_DIRECT_CMD_MAIN_SETTINGS);
244
245 /* MIPI DCS command is part of the data */
246 if (txlen > 0) {
247 val = 0;
248 for (i = 0; i < 4 && i < txlen; i++)
249 val |= tx[i] << (i * 8);
250 }
251 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT0);
252 if (txlen > 4) {
253 val = 0;
254 for (i = 0; i < 4 && (i + 4) < txlen; i++)
255 val |= tx[i + 4] << (i * 8);
256 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT1);
257 }
258 if (txlen > 8) {
259 val = 0;
260 for (i = 0; i < 4 && (i + 8) < txlen; i++)
261 val |= tx[i + 8] << (i * 8);
262 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT2);
263 }
264 if (txlen > 12) {
265 val = 0;
266 for (i = 0; i < 4 && (i + 12) < txlen; i++)
267 val |= tx[i + 12] << (i * 8);
268 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT3);
269 }
270 221
271 writel(~0, d->regs + DSI_DIRECT_CMD_STS_CLR);222 writel(~0, d->regs + DSI_DIRECT_CMD_STS_CLR);
272 writel(~0, d->regs + DSI_CMD_MODE_STS_CLR);223 writel(~0, d->regs + DSI_CMD_MODE_STS_CLR);
@@ -283,6 +234,7 @@ static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host, · 10 unmodified lines
283 usleep_range(loop_delay_us, (loop_delay_us * 3) / 2);234 usleep_range(loop_delay_us, (loop_delay_us * 3) / 2);
284 if (!loop_counter) {235 if (!loop_counter) {
285 dev_err(d->dev, "DSI read timeout!\n");236 dev_err(d->dev, "DSI read timeout!\n");
237 /* Set exit code and retry */
286 return -ETIME;238 return -ETIME;
287 }239 }
288 } else {240 } else {
@@ -293,6 +245,7 @@ static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host, · 4 unmodified lines
293 usleep_range(loop_delay_us, (loop_delay_us * 3) / 2);245 usleep_range(loop_delay_us, (loop_delay_us * 3) / 2);
294 246
295 if (!loop_counter) {247 if (!loop_counter) {
248 /* Set exit code and retry */
296 dev_err(d->dev, "DSI write timeout!\n");249 dev_err(d->dev, "DSI write timeout!\n");
297 return -ETIME;250 return -ETIME;
298 }251 }
@@ -334,6 +287,93 @@ static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host, · 35 unmodified lines
334 ret = rdsz;287 ret = rdsz;
335 }288 }
336 289
290 /* Successful transmission */
291 return ret;
292}
293
294static ssize_t mcde_dsi_host_transfer(struct mipi_dsi_host *host,
295 const struct mipi_dsi_msg *msg)
296{
297 struct mcde_dsi *d = host_to_mcde_dsi(host);
298 const u8 *tx = msg->tx_buf;
299 size_t txlen = msg->tx_len;
300 size_t rxlen = msg->rx_len;
301 unsigned int retries = 0;
302 u32 val;
303 int ret;
304 int i;
305
306 if (txlen > 16) {
307 dev_err(d->dev,
308 "dunno how to write more than 16 bytes yet\n");
309 return -EIO;
310 }
311 if (rxlen > 4) {
312 dev_err(d->dev,
313 "dunno how to read more than 4 bytes yet\n");
314 return -EIO;
315 }
316
317 dev_dbg(d->dev,
318 "message to channel %d, write %zd bytes read %zd bytes\n",
319 msg->channel, txlen, rxlen);
320
321 /* Command "nature" */
322 if (MCDE_DSI_HOST_IS_READ(msg->type))
323 /* MCTL_MAIN_DATA_CTL already set up */
324 val = DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_READ;
325 else
326 val = DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_NAT_WRITE;
327 /*
328 * More than 2 bytes will not fit in a single packet, so it's
329 * time to set the "long not short" bit. One byte is used by
330 * the MIPI DCS command leaving just one byte for the payload
331 * in a short package.
332 */
333 if (mipi_dsi_packet_format_is_long(msg->type))
334 val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LONGNOTSHORT;
335 val |= 0 << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_ID_SHIFT;
336 val |= txlen << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_SIZE_SHIFT;
337 val |= DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_LP_EN;
338 val |= msg->type << DSI_DIRECT_CMD_MAIN_SETTINGS_CMD_HEAD_SHIFT;
339 writel(val, d->regs + DSI_DIRECT_CMD_MAIN_SETTINGS);
340
341 /* MIPI DCS command is part of the data */
342 if (txlen > 0) {
343 val = 0;
344 for (i = 0; i < 4 && i < txlen; i++)
345 val |= tx[i] << (i * 8);
346 }
347 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT0);
348 if (txlen > 4) {
349 val = 0;
350 for (i = 0; i < 4 && (i + 4) < txlen; i++)
351 val |= tx[i + 4] << (i * 8);
352 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT1);
353 }
354 if (txlen > 8) {
355 val = 0;
356 for (i = 0; i < 4 && (i + 8) < txlen; i++)
357 val |= tx[i + 8] << (i * 8);
358 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT2);
359 }
360 if (txlen > 12) {
361 val = 0;
362 for (i = 0; i < 4 && (i + 12) < txlen; i++)
363 val |= tx[i + 12] << (i * 8);
364 writel(val, d->regs + DSI_DIRECT_CMD_WRDAT3);
365 }
366
367 while (retries < 3) {
368 ret = mcde_dsi_execute_transfer(d, msg);
369 if (ret >= 0)
370 break;
371 retries++;
372 }
373 if (ret < 0 && retries)
374 dev_err(d->dev, "gave up after %d retries\n", retries);
375
376 /* Clear any errors */
337 writel(~0, d->regs + DSI_DIRECT_CMD_STS_CLR);377 writel(~0, d->regs + DSI_DIRECT_CMD_STS_CLR);
338 writel(~0, d->regs + DSI_CMD_MODE_STS_CLR);378 writel(~0, d->regs + DSI_CMD_MODE_STS_CLR);
339 379
@@ -799,10 +839,11 @@ static void mcde_dsi_start(struct mcde_dsi *d) · 459 unmodified lines
799 /* Command mode, clear IF1 ID */839 /* Command mode, clear IF1 ID */
800 val = readl(d->regs + DSI_CMD_MODE_CTL);840 val = readl(d->regs + DSI_CMD_MODE_CTL);
801 /*841 /*
802 * If we enable low-power mode here, with842 * If we enable low-power mode here,
803 * val |= DSI_CMD_MODE_CTL_IF1_LP_EN
804 * then display updates become really slow.843 * then display updates become really slow.
805 */844 */
845 if (d->mdsi->mode_flags & MIPI_DSI_MODE_LPM)
846 val |= DSI_CMD_MODE_CTL_IF1_LP_EN;
806 val &= ~DSI_CMD_MODE_CTL_IF1_ID_MASK;847 val &= ~DSI_CMD_MODE_CTL_IF1_ID_MASK;
807 writel(val, d->regs + DSI_CMD_MODE_CTL);848 writel(val, d->regs + DSI_CMD_MODE_CTL);
808 849
@@ -811,23 +852,11 @@ static void mcde_dsi_start(struct mcde_dsi *d) · 2 unmodified lines
811 dev_info(d->dev, "DSI link enabled\n");852 dev_info(d->dev, "DSI link enabled\n");
812}853}
813 854
814 855/*
815static void mcde_dsi_bridge_enable(struct drm_bridge *bridge)856 * Notice that this is called from inside the display controller
816{857 * and not from the bridge callbacks.
817 struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);858 */
818 u32 val;859void mcde_dsi_enable(struct drm_bridge *bridge)
819
820 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
821 /* Enable video mode */
822 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
823 val |= DSI_MCTL_MAIN_DATA_CTL_VID_EN;
824 writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
825 }
826
827 dev_info(d->dev, "enable DSI master\n");
828};
829
830static void mcde_dsi_bridge_pre_enable(struct drm_bridge *bridge)
831{860{
832 struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);861 struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
833 unsigned long hs_freq, lp_freq;862 unsigned long hs_freq, lp_freq;
@@ -871,7 +900,25 @@ static void mcde_dsi_bridge_pre_enable(struct drm_bridge *bridge) · 37 unmodified lines
871 dev_info(d->dev, "DSI HS clock rate %lu Hz\n",900 dev_info(d->dev, "DSI HS clock rate %lu Hz\n",
872 d->hs_freq);901 d->hs_freq);
873 902
903 /* Assert RESET through the PRCMU, active low */
904 /* FIXME: which DSI block? */
905 regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
906 PRCM_DSI_SW_RESET_DSI0_SW_RESETN, 0);
907
908 usleep_range(100, 200);
909
910 /* De-assert RESET again */
911 regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
912 PRCM_DSI_SW_RESET_DSI0_SW_RESETN,
913 PRCM_DSI_SW_RESET_DSI0_SW_RESETN);
914
915 /* Start up the hardware */
916 mcde_dsi_start(d);
917
874 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {918 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
919 /* Set up the video mode from the DRM mode */
920 mcde_dsi_setup_video_mode(d, d->mode);
921
875 /* Put IF1 into video mode */922 /* Put IF1 into video mode */
876 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);923 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
877 val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE;924 val |= DSI_MCTL_MAIN_DATA_CTL_IF1_MODE;
@@ -887,17 +934,25 @@ static void mcde_dsi_bridge_pre_enable(struct drm_bridge *bridge) · 9 unmodified lines
887 val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC;934 val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_VSYNC;
888 val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA;935 val |= DSI_VID_MODE_STS_CTL_ERR_MISSING_DATA;
889 writel(val, d->regs + DSI_VID_MODE_STS_CTL);936 writel(val, d->regs + DSI_VID_MODE_STS_CTL);
937
938 /* Enable video mode */
939 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
940 val |= DSI_MCTL_MAIN_DATA_CTL_VID_EN;
941 writel(val, d->regs + DSI_MCTL_MAIN_DATA_CTL);
890 } else {942 } else {
891 /* Command mode, clear IF1 ID */943 /* Command mode, clear IF1 ID */
892 val = readl(d->regs + DSI_CMD_MODE_CTL);944 val = readl(d->regs + DSI_CMD_MODE_CTL);
893 /*945 /*
894 * If we enable low-power mode here with946 * If we enable low-power mode here
895 * val |= DSI_CMD_MODE_CTL_IF1_LP_EN
896 * the display updates become really slow.947 * the display updates become really slow.
897 */948 */
949 if (d->mdsi->mode_flags & MIPI_DSI_MODE_LPM)
950 val |= DSI_CMD_MODE_CTL_IF1_LP_EN;
898 val &= ~DSI_CMD_MODE_CTL_IF1_ID_MASK;951 val &= ~DSI_CMD_MODE_CTL_IF1_ID_MASK;
899 writel(val, d->regs + DSI_CMD_MODE_CTL);952 writel(val, d->regs + DSI_CMD_MODE_CTL);
900 }953 }
954
955 dev_info(d->dev, "enabled MCDE DSI master\n");
901}956}
902 957
903static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,958static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge,
@@ -911,13 +966,12 @@ static void mcde_dsi_bridge_mode_set(struct drm_bridge *bridge, · 7 unmodified lines
911 return;966 return;
912 }967 }
913 968
969 d->mode = mode;
970
914 dev_info(d->dev, "set DSI master to %dx%d %u Hz %s mode\n",971 dev_info(d->dev, "set DSI master to %dx%d %u Hz %s mode\n",
915 mode->hdisplay, mode->vdisplay, mode->clock * 1000,972 mode->hdisplay, mode->vdisplay, mode->clock * 1000,
916 (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD"973 (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) ? "VIDEO" : "CMD"
917 );974 );
918
919 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO)
920 mcde_dsi_setup_video_mode(d, mode);
921}975}
922 976
923static void mcde_dsi_wait_for_command_mode_stop(struct mcde_dsi *d)977static void mcde_dsi_wait_for_command_mode_stop(struct mcde_dsi *d)
@@ -961,14 +1015,15 @@ static void mcde_dsi_wait_for_video_mode_stop(struct mcde_dsi *d) · 37 unmodified lines
961 }1015 }
962}1016}
963 1017
964static void mcde_dsi_bridge_disable(struct drm_bridge *bridge)1018/*
1019 * Notice that this is called from inside the display controller
1020 * and not from the bridge callbacks.
1021 */
1022void mcde_dsi_disable(struct drm_bridge *bridge)
965{1023{
966 struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);1024 struct mcde_dsi *d = bridge_to_mcde_dsi(bridge);
967 u32 val;1025 u32 val;
968 1026
969 /* Disable all error interrupts */
970 writel(0, d->regs + DSI_VID_MODE_STS_CTL);
971
972 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {1027 if (d->mdsi->mode_flags & MIPI_DSI_MODE_VIDEO) {
973 /* Stop video mode */1028 /* Stop video mode */
974 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);1029 val = readl(d->regs + DSI_MCTL_MAIN_DATA_CTL);
@@ -980,7 +1035,14 @@ static void mcde_dsi_bridge_disable(struct drm_bridge *bridge) · 5 unmodified lines
980 mcde_dsi_wait_for_command_mode_stop(d);1035 mcde_dsi_wait_for_command_mode_stop(d);
981 }1036 }
982 1037
983 /* Stop clocks */1038 /*
1039 * Stop clocks and terminate any DSI traffic here so the panel can
1040 * send commands to shut down the display using DSI direct write until
1041 * this point.
1042 */
1043
1044 /* Disable all error interrupts */
1045 writel(0, d->regs + DSI_VID_MODE_STS_CTL);
984 clk_disable_unprepare(d->hs_clk);1046 clk_disable_unprepare(d->hs_clk);
985 clk_disable_unprepare(d->lp_clk);1047 clk_disable_unprepare(d->lp_clk);
986}1048}
@@ -1010,9 +1072,6 @@ static int mcde_dsi_bridge_attach(struct drm_bridge *bridge, · 23 unmodified lines
1010static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = {1072static const struct drm_bridge_funcs mcde_dsi_bridge_funcs = {
1011 .attach = mcde_dsi_bridge_attach,1073 .attach = mcde_dsi_bridge_attach,
1012 .mode_set = mcde_dsi_bridge_mode_set,1074 .mode_set = mcde_dsi_bridge_mode_set,
1013 .disable = mcde_dsi_bridge_disable,
1014 .enable = mcde_dsi_bridge_enable,
1015 .pre_enable = mcde_dsi_bridge_pre_enable,
1016};1075};
1017 1076
1018static int mcde_dsi_bind(struct device *dev, struct device *master,1077static int mcde_dsi_bind(struct device *dev, struct device *master,
@@ -1048,21 +1107,6 @@ static int mcde_dsi_bind(struct device *dev, struct device *master, · 29 unmodified lines
1048 return PTR_ERR(d->lp_clk);1107 return PTR_ERR(d->lp_clk);
1049 }1108 }
1050 1109
1051 /* Assert RESET through the PRCMU, active low */
1052 /* FIXME: which DSI block? */
1053 regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
1054 PRCM_DSI_SW_RESET_DSI0_SW_RESETN, 0);
1055
1056 usleep_range(100, 200);
1057
1058 /* De-assert RESET again */
1059 regmap_update_bits(d->prcmu, PRCM_DSI_SW_RESET,
1060 PRCM_DSI_SW_RESET_DSI0_SW_RESETN,
1061 PRCM_DSI_SW_RESET_DSI0_SW_RESETN);
1062
1063 /* Start up the hardware */
1064 mcde_dsi_start(d);
1065
1066 /* Look for a panel as a child to this node */1110 /* Look for a panel as a child to this node */
1067 for_each_available_child_of_node(dev->of_node, child) {1111 for_each_available_child_of_node(dev->of_node, child) {
1068 panel = of_drm_find_panel(child);1112 panel = of_drm_find_panel(child);
drivers/gpu/drm/mgag200/Kconfig+5−7
@@ -1,13 +1,11 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2config DRM_MGAG2002config DRM_MGAG200
3 tristate "Kernel modesetting driver for MGA G200 server engines"3 tristate "Matrox G200"
4 depends on DRM && PCI && MMU4 depends on DRM && PCI && MMU
5 select DRM_GEM_SHMEM_HELPER5 select DRM_GEM_SHMEM_HELPER
6 select DRM_KMS_HELPER6 select DRM_KMS_HELPER
7 help7 help
8 This is a KMS driver for the MGA G200 server chips, it8 This is a KMS driver for Matrox G200 chips. It supports the original
9 does not support the original MGA G200 or any of the desktop9 MGA G200 desktop chips and the server variants. It requires 0.3.0
10 chips. It requires 0.3.0 of the modesetting userspace driver,10 of the modesetting userspace driver, and a version of mga driver
11 and a version of mga driver that will fail on KMS enabled11 that will fail on KMS enabled devices.
12 devices.
13
drivers/gpu/drm/mgag200/mgag200_drv.c+215−12
@@ -9,6 +9,7 @@ · 8 unmodified lines
9#include <linux/console.h>9#include <linux/console.h>
10#include <linux/module.h>10#include <linux/module.h>
11#include <linux/pci.h>11#include <linux/pci.h>
12#include <linux/vmalloc.h>
12 13
13#include <drm/drm_drv.h>14#include <drm/drm_drv.h>
14#include <drm/drm_file.h>15#include <drm/drm_file.h>
@@ -36,6 +37,7 @@ static struct drm_driver mgag200_driver = { · 21 unmodified lines
36 .major = DRIVER_MAJOR,37 .major = DRIVER_MAJOR,
37 .minor = DRIVER_MINOR,38 .minor = DRIVER_MINOR,
38 .patchlevel = DRIVER_PATCHLEVEL,39 .patchlevel = DRIVER_PATCHLEVEL,
40 .gem_create_object = drm_gem_shmem_create_object_cached,
39 DRM_GEM_SHMEM_DRIVER_OPS,41 DRM_GEM_SHMEM_DRIVER_OPS,
40};42};
41 43
@@ -43,18 +45,66 @@ static struct drm_driver mgag200_driver = { · 1 unmodified line
43 * DRM device45 * DRM device
44 */46 */
45 47
46static int mgag200_device_init(struct mga_device *mdev, unsigned long flags)48static bool mgag200_has_sgram(struct mga_device *mdev)
47{49{
48 struct drm_device *dev = &mdev->base;50 struct drm_device *dev = &mdev->base;
49 int ret, option;51 u32 option;
52 int ret;
50 53
51 mdev->flags = mgag200_flags_from_driver_data(flags);54 ret = pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option);
52 mdev->type = mgag200_type_from_driver_data(flags);55 if (drm_WARN(dev, ret, "failed to read PCI config dword: %d\n", ret))
56 return false;
53 57
54 pci_read_config_dword(dev->pdev, PCI_MGA_OPTION, &option);58 return !!(option & PCI_MGA_OPTION_HARDPWMSK);
55 mdev->has_sdram = !(option & (1 << 14));59}
56 60
57 /* BAR 0 is the framebuffer, BAR 1 contains registers */61static int mgag200_regs_init(struct mga_device *mdev)
62{
63 struct drm_device *dev = &mdev->base;
64 u32 option, option2;
65 u8 crtcext3;
66
67 switch (mdev->type) {
68 case G200_PCI:
69 case G200_AGP:
70 if (mgag200_has_sgram(mdev))
71 option = 0x4049cd21;
72 else
73 option = 0x40499121;
74 option2 = 0x00008000;
75 break;
76 case G200_SE_A:
77 case G200_SE_B:
78 option = 0x40049120;
79 if (mgag200_has_sgram(mdev))
80 option |= PCI_MGA_OPTION_HARDPWMSK;
81 option2 = 0x00008000;
82 break;
83 case G200_WB:
84 case G200_EW3:
85 option = 0x41049120;
86 option2 = 0x0000b000;
87 break;
88 case G200_EV:
89 option = 0x00000120;
90 option2 = 0x0000b000;
91 break;
92 case G200_EH:
93 case G200_EH3:
94 option = 0x00000120;
95 option2 = 0x0000b000;
96 break;
97 default:
98 option = 0;
99 option2 = 0;
100 }
101
102 if (option)
103 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
104 if (option2)
105 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
106
107 /* BAR 1 contains registers */
58 mdev->rmmio_base = pci_resource_start(dev->pdev, 1);108 mdev->rmmio_base = pci_resource_start(dev->pdev, 1);
59 mdev->rmmio_size = pci_resource_len(dev->pdev, 1);109 mdev->rmmio_size = pci_resource_len(dev->pdev, 1);
60 110
@@ -68,12 +118,163 @@ static int mgag200_device_init(struct mga_device *mdev, unsigned long flags) · 7 unmodified lines
68 if (mdev->rmmio == NULL)118 if (mdev->rmmio == NULL)
69 return -ENOMEM;119 return -ENOMEM;
70 120
71 /* stash G200 SE model number for later use */121 RREG_ECRT(0x03, crtcext3);
72 if (IS_G200_SE(mdev)) {122 crtcext3 |= MGAREG_CRTCEXT3_MGAMODE;
73 mdev->unique_rev_id = RREG32(0x1e24);123 WREG_ECRT(0x03, crtcext3);
74 drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",124
75 mdev->unique_rev_id);125 return 0;
126}
127
128static void mgag200_g200_interpret_bios(struct mga_device *mdev,
129 const unsigned char *bios,
130 size_t size)
131{
132 static const char matrox[] = {'M', 'A', 'T', 'R', 'O', 'X'};
133 static const unsigned int expected_length[6] = {
134 0, 64, 64, 64, 128, 128
135 };
136 struct drm_device *dev = &mdev->base;
137 const unsigned char *pins;
138 unsigned int pins_len, version;
139 int offset;
140 int tmp;
141
142 /* Test for MATROX string. */
143 if (size < 45 + sizeof(matrox))
144 return;
145 if (memcmp(&bios[45], matrox, sizeof(matrox)) != 0)
146 return;
147
148 /* Get the PInS offset. */
149 if (size < MGA_BIOS_OFFSET + 2)
150 return;
151 offset = (bios[MGA_BIOS_OFFSET + 1] << 8) | bios[MGA_BIOS_OFFSET];
152
153 /* Get PInS data structure. */
154
155 if (size < offset + 6)
156 return;
157 pins = bios + offset;
158 if (pins[0] == 0x2e && pins[1] == 0x41) {
159 version = pins[5];
160 pins_len = pins[2];
161 } else {
162 version = 1;
163 pins_len = pins[0] + (pins[1] << 8);
164 }
165
166 if (version < 1 || version > 5) {
167 drm_warn(dev, "Unknown BIOS PInS version: %d\n", version);
168 return;
169 }
170 if (pins_len != expected_length[version]) {
171 drm_warn(dev, "Unexpected BIOS PInS size: %d expected: %d\n",
172 pins_len, expected_length[version]);
173 return;
76 }174 }
175 if (size < offset + pins_len)
176 return;
177
178 drm_dbg_kms(dev, "MATROX BIOS PInS version %d size: %d found\n",
179 version, pins_len);
180
181 /* Extract the clock values */
182
183 switch (version) {
184 case 1:
185 tmp = pins[24] + (pins[25] << 8);
186 if (tmp)
187 mdev->model.g200.pclk_max = tmp * 10;
188 break;
189 case 2:
190 if (pins[41] != 0xff)
191 mdev->model.g200.pclk_max = (pins[41] + 100) * 1000;
192 break;
193 case 3:
194 if (pins[36] != 0xff)
195 mdev->model.g200.pclk_max = (pins[36] + 100) * 1000;
196 if (pins[52] & 0x20)
197 mdev->model.g200.ref_clk = 14318;
198 break;
199 case 4:
200 if (pins[39] != 0xff)
201 mdev->model.g200.pclk_max = pins[39] * 4 * 1000;
202 if (pins[92] & 0x01)
203 mdev->model.g200.ref_clk = 14318;
204 break;
205 case 5:
206 tmp = pins[4] ? 8000 : 6000;
207 if (pins[123] != 0xff)
208 mdev->model.g200.pclk_min = pins[123] * tmp;
209 if (pins[38] != 0xff)
210 mdev->model.g200.pclk_max = pins[38] * tmp;
211 if (pins[110] & 0x01)
212 mdev->model.g200.ref_clk = 14318;
213 break;
214 default:
215 break;
216 }
217}
218
219static void mgag200_g200_init_refclk(struct mga_device *mdev)
220{
221 struct drm_device *dev = &mdev->base;
222 unsigned char __iomem *rom;
223 unsigned char *bios;
224 size_t size;
225
226 mdev->model.g200.pclk_min = 50000;
227 mdev->model.g200.pclk_max = 230000;
228 mdev->model.g200.ref_clk = 27050;
229
230 rom = pci_map_rom(dev->pdev, &size);
231 if (!rom)
232 return;
233
234 bios = vmalloc(size);
235 if (!bios)
236 goto out;
237 memcpy_fromio(bios, rom, size);
238
239 if (size != 0 && bios[0] == 0x55 && bios[1] == 0xaa)
240 mgag200_g200_interpret_bios(mdev, bios, size);
241
242 drm_dbg_kms(dev, "pclk_min: %ld pclk_max: %ld ref_clk: %ld\n",
243 mdev->model.g200.pclk_min, mdev->model.g200.pclk_max,
244 mdev->model.g200.ref_clk);
245
246 vfree(bios);
247out:
248 pci_unmap_rom(dev->pdev, rom);
249}
250
251static void mgag200_g200se_init_unique_id(struct mga_device *mdev)
252{
253 struct drm_device *dev = &mdev->base;
254
255 /* stash G200 SE model number for later use */
256 mdev->model.g200se.unique_rev_id = RREG32(0x1e24);
257
258 drm_dbg(dev, "G200 SE unique revision id is 0x%x\n",
259 mdev->model.g200se.unique_rev_id);
260}
261
262static int mgag200_device_init(struct mga_device *mdev, unsigned long flags)
263{
264 struct drm_device *dev = &mdev->base;
265 int ret;
266
267 mdev->flags = mgag200_flags_from_driver_data(flags);
268 mdev->type = mgag200_type_from_driver_data(flags);
269
270 ret = mgag200_regs_init(mdev);
271 if (ret)
272 return ret;
273
274 if (mdev->type == G200_PCI || mdev->type == G200_AGP)
275 mgag200_g200_init_refclk(mdev);
276 else if (IS_G200_SE(mdev))
277 mgag200_g200se_init_unique_id(mdev);
77 278
78 ret = mgag200_mm_init(mdev);279 ret = mgag200_mm_init(mdev);
79 if (ret)280 if (ret)
@@ -116,6 +317,8 @@ mgag200_device_create(struct pci_dev *pdev, unsigned long flags) · 36 unmodified lines
116 */317 */
117 318
118static const struct pci_device_id mgag200_pciidlist[] = {319static const struct pci_device_id mgag200_pciidlist[] = {
320 { PCI_VENDOR_ID_MATROX, 0x520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_PCI },
321 { PCI_VENDOR_ID_MATROX, 0x521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_AGP },
119 { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,322 { PCI_VENDOR_ID_MATROX, 0x522, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
120 G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},323 G200_SE_A | MGAG200_FLAG_HW_BUG_NO_STARTADD},
121 { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },324 { PCI_VENDOR_ID_MATROX, 0x524, PCI_ANY_ID, PCI_ANY_ID, 0, 0, G200_SE_B },
drivers/gpu/drm/mgag200/mgag200_drv.h+16−3
@@ -38,6 +38,8 @@ · 37 unmodified lines
38#define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg))38#define RREG32(reg) ioread32(((void __iomem *)mdev->rmmio) + (reg))
39#define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg))39#define WREG32(reg, v) iowrite32(v, ((void __iomem *)mdev->rmmio) + (reg))
40 40
41#define MGA_BIOS_OFFSET 0x7ffc
42
41#define ATTR_INDEX 0x1fc043#define ATTR_INDEX 0x1fc0
42#define ATTR_DATA 0x1fc144#define ATTR_DATA 0x1fc1
43 45
@@ -129,6 +131,8 @@ struct mga_mc { · 85 unmodified lines
129};131};
130 132
131enum mga_type {133enum mga_type {
134 G200_PCI,
135 G200_AGP,
132 G200_SE_A,136 G200_SE_A,
133 G200_SE_B,137 G200_SE_B,
134 G200_WB,138 G200_WB,
@@ -161,14 +165,23 @@ struct mga_device { · 26 unmodified lines
161 size_t vram_fb_available;165 size_t vram_fb_available;
162 166
163 enum mga_type type;167 enum mga_type type;
164 int has_sdram;
165 168
166 int bpp_shifts[4];169 int bpp_shifts[4];
167 170
168 int fb_mtrr;171 int fb_mtrr;
169 172
170 /* SE model number stored in reg 0x1e24 */173 union {
171 u32 unique_rev_id;174 struct {
175 long ref_clk;
176 long pclk_min;
177 long pclk_max;
178 } g200;
179 struct {
180 /* SE model number stored in reg 0x1e24 */
181 u32 unique_rev_id;
182 } g200se;
183 } model;
184
172 185
173 struct mga_connector connector;186 struct mga_connector connector;
174 struct drm_simple_display_pipe display_pipe;187 struct drm_simple_display_pipe display_pipe;
drivers/gpu/drm/mgag200/mgag200_mm.c+8−0
@@ -90,9 +90,17 @@ static void mgag200_mm_release(struct drm_device *dev, void *ptr) · 89 unmodified lines
90int mgag200_mm_init(struct mga_device *mdev)90int mgag200_mm_init(struct mga_device *mdev)
91{91{
92 struct drm_device *dev = &mdev->base;92 struct drm_device *dev = &mdev->base;
93 u8 misc;
93 resource_size_t start, len;94 resource_size_t start, len;
94 int ret;95 int ret;
95 96
97 WREG_ECRT(0x04, 0x00);
98
99 misc = RREG8(MGA_MISC_IN);
100 misc |= MGAREG_MISC_RAMMAPEN |
101 MGAREG_MISC_HIGH_PG_SEL;
102 WREG8(MGA_MISC_OUT, misc);
103
96 /* BAR 0 is VRAM */104 /* BAR 0 is VRAM */
97 start = pci_resource_start(dev->pdev, 0);105 start = pci_resource_start(dev->pdev, 0);
98 len = pci_resource_len(dev->pdev, 0);106 len = pci_resource_len(dev->pdev, 0);
drivers/gpu/drm/mgag200/mgag200_mode.c+93−60
@@ -9,7 +9,6 @@ · 8 unmodified lines
9 */9 */
10 10
11#include <linux/delay.h>11#include <linux/delay.h>
12#include <linux/pci.h>
13 12
14#include <drm/drm_atomic_helper.h>13#include <drm/drm_atomic_helper.h>
15#include <drm/drm_atomic_state_helper.h>14#include <drm/drm_atomic_state_helper.h>
@@ -109,10 +108,82 @@ static inline void mga_wait_busy(struct mga_device *mdev) · 93 unmodified lines
109 } while ((status & 0x01) && time_before(jiffies, timeout));108 } while ((status & 0x01) && time_before(jiffies, timeout));
110}109}
111 110
111/*
112 * PLL setup
113 */
114
115static int mgag200_g200_set_plls(struct mga_device *mdev, long clock)
116{
117 struct drm_device *dev = &mdev->base;
118 const int post_div_max = 7;
119 const int in_div_min = 1;
120 const int in_div_max = 6;
121 const int feed_div_min = 7;
122 const int feed_div_max = 127;
123 u8 testm, testn;
124 u8 n = 0, m = 0, p, s;
125 long f_vco;
126 long computed;
127 long delta, tmp_delta;
128 long ref_clk = mdev->model.g200.ref_clk;
129 long p_clk_min = mdev->model.g200.pclk_min;
130 long p_clk_max = mdev->model.g200.pclk_max;
131
132 if (clock > p_clk_max) {
133 drm_err(dev, "Pixel Clock %ld too high\n", clock);
134 return 1;
135 }
136
137 if (clock < p_clk_min >> 3)
138 clock = p_clk_min >> 3;
139
140 f_vco = clock;
141 for (p = 0;
142 p <= post_div_max && f_vco < p_clk_min;
143 p = (p << 1) + 1, f_vco <<= 1)
144 ;
145
146 delta = clock;
147
148 for (testm = in_div_min; testm <= in_div_max; testm++) {
149 for (testn = feed_div_min; testn <= feed_div_max; testn++) {
150 computed = ref_clk * (testn + 1) / (testm + 1);
151 if (computed < f_vco)
152 tmp_delta = f_vco - computed;
153 else
154 tmp_delta = computed - f_vco;
155 if (tmp_delta < delta) {
156 delta = tmp_delta;
157 m = testm;
158 n = testn;
159 }
160 }
161 }
162 f_vco = ref_clk * (n + 1) / (m + 1);
163 if (f_vco < 100000)
164 s = 0;
165 else if (f_vco < 140000)
166 s = 1;
167 else if (f_vco < 180000)
168 s = 2;
169 else
170 s = 3;
171
172 drm_dbg_kms(dev, "clock: %ld vco: %ld m: %d n: %d p: %d s: %d\n",
173 clock, f_vco, m, n, p, s);
174
175 WREG_DAC(MGA1064_PIX_PLLC_M, m);
176 WREG_DAC(MGA1064_PIX_PLLC_N, n);
177 WREG_DAC(MGA1064_PIX_PLLC_P, (p | (s << 3)));
178
179 return 0;
180}
181
112#define P_ARRAY_SIZE 9182#define P_ARRAY_SIZE 9
113 183
114static int mga_g200se_set_plls(struct mga_device *mdev, long clock)184static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
115{185{
186 u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
116 unsigned int vcomax, vcomin, pllreffreq;187 unsigned int vcomax, vcomin, pllreffreq;
117 unsigned int delta, tmpdelta, permitteddelta;188 unsigned int delta, tmpdelta, permitteddelta;
118 unsigned int testp, testm, testn;189 unsigned int testp, testm, testn;
@@ -122,7 +193,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) · 3 unmodified lines
122 unsigned int fvv;193 unsigned int fvv;
123 unsigned int i;194 unsigned int i;
124 195
125 if (mdev->unique_rev_id <= 0x03) {196 if (unique_rev_id <= 0x03) {
126 197
127 m = n = p = 0;198 m = n = p = 0;
128 vcomax = 320000;199 vcomax = 320000;
@@ -220,7 +291,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock) · 91 unmodified lines
220 WREG_DAC(MGA1064_PIX_PLLC_N, n);291 WREG_DAC(MGA1064_PIX_PLLC_N, n);
221 WREG_DAC(MGA1064_PIX_PLLC_P, p);292 WREG_DAC(MGA1064_PIX_PLLC_P, p);
222 293
223 if (mdev->unique_rev_id >= 0x04) {294 if (unique_rev_id >= 0x04) {
224 WREG_DAC(0x1a, 0x09);295 WREG_DAC(0x1a, 0x09);
225 msleep(20);296 msleep(20);
226 WREG_DAC(0x1a, 0x01);297 WREG_DAC(0x1a, 0x01);
@@ -717,6 +788,9 @@ static int mgag200_crtc_set_plls(struct mga_device *mdev, long clock) · 490 unmodified lines
717 u8 misc;788 u8 misc;
718 789
719 switch(mdev->type) {790 switch(mdev->type) {
791 case G200_PCI:
792 case G200_AGP:
793 return mgag200_g200_set_plls(mdev, clock);
720 case G200_SE_A:794 case G200_SE_A:
721 case G200_SE_B:795 case G200_SE_B:
722 return mga_g200se_set_plls(mdev, clock);796 return mga_g200se_set_plls(mdev, clock);
@@ -877,45 +951,6 @@ static void mgag200_set_startadd(struct mga_device *mdev, · 154 unmodified lines
877 WREG_ECRT(0x00, crtcext0);951 WREG_ECRT(0x00, crtcext0);
878}952}
879 953
880static void mgag200_set_pci_regs(struct mga_device *mdev)
881{
882 uint32_t option = 0, option2 = 0;
883 struct drm_device *dev = &mdev->base;
884
885 switch (mdev->type) {
886 case G200_SE_A:
887 case G200_SE_B:
888 if (mdev->has_sdram)
889 option = 0x40049120;
890 else
891 option = 0x4004d120;
892 option2 = 0x00008000;
893 break;
894 case G200_WB:
895 case G200_EW3:
896 option = 0x41049120;
897 option2 = 0x0000b000;
898 break;
899 case G200_EV:
900 option = 0x00000120;
901 option2 = 0x0000b000;
902 break;
903 case G200_EH:
904 case G200_EH3:
905 option = 0x00000120;
906 option2 = 0x0000b000;
907 break;
908 case G200_ER:
909 break;
910 }
911
912 if (option)
913 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION, option);
914
915 if (option2)
916 pci_write_config_dword(dev->pdev, PCI_MGA_OPTION2, option2);
917}
918
919static void mgag200_set_dac_regs(struct mga_device *mdev)954static void mgag200_set_dac_regs(struct mga_device *mdev)
920{955{
921 size_t i;956 size_t i;
@@ -933,6 +968,12 @@ static void mgag200_set_dac_regs(struct mga_device *mdev) · 11 unmodified lines
933 };968 };
934 969
935 switch (mdev->type) {970 switch (mdev->type) {
971 case G200_PCI:
972 case G200_AGP:
973 dacvalue[MGA1064_SYS_PLL_M] = 0x04;
974 dacvalue[MGA1064_SYS_PLL_N] = 0x2D;
975 dacvalue[MGA1064_SYS_PLL_P] = 0x19;
976 break;
936 case G200_SE_A:977 case G200_SE_A:
937 case G200_SE_B:978 case G200_SE_B:
938 dacvalue[MGA1064_VREF_CTL] = 0x03;979 dacvalue[MGA1064_VREF_CTL] = 0x03;
@@ -986,9 +1027,8 @@ static void mgag200_set_dac_regs(struct mga_device *mdev) · 47 unmodified lines
986 1027
987static void mgag200_init_regs(struct mga_device *mdev)1028static void mgag200_init_regs(struct mga_device *mdev)
988{1029{
989 u8 crtc11, crtcext3, crtcext4, misc;1030 u8 crtc11, misc;
990 1031
991 mgag200_set_pci_regs(mdev);
992 mgag200_set_dac_regs(mdev);1032 mgag200_set_dac_regs(mdev);
993 1033
994 WREG_SEQ(2, 0x0f);1034 WREG_SEQ(2, 0x0f);
@@ -1002,14 +1042,6 @@ static void mgag200_init_regs(struct mga_device *mdev) · 7 unmodified lines
1002 WREG_CRT(14, 0);1042 WREG_CRT(14, 0);
1003 WREG_CRT(15, 0);1043 WREG_CRT(15, 0);
1004 1044
1005 RREG_ECRT(0x03, crtcext3);
1006
1007 crtcext3 |= BIT(7); /* enable MGA mode */
1008 crtcext4 = 0x00;
1009
1010 WREG_ECRT(0x03, crtcext3);
1011 WREG_ECRT(0x04, crtcext4);
1012
1013 RREG_CRT(0x11, crtc11);1045 RREG_CRT(0x11, crtc11);
1014 crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT |1046 crtc11 &= ~(MGAREG_CRTC11_CRTCPROTECT |
1015 MGAREG_CRTC11_VINTEN |1047 MGAREG_CRTC11_VINTEN |
@@ -1023,9 +1055,7 @@ static void mgag200_init_regs(struct mga_device *mdev) · 7 unmodified lines
1023 WREG_ECRT(0x34, 0x5);1055 WREG_ECRT(0x34, 0x5);
1024 1056
1025 misc = RREG8(MGA_MISC_IN);1057 misc = RREG8(MGA_MISC_IN);
1026 misc |= MGAREG_MISC_IOADSEL |1058 misc |= MGAREG_MISC_IOADSEL;
1027 MGAREG_MISC_RAMMAPEN |
1028 MGAREG_MISC_HIGH_PG_SEL;
1029 WREG8(MGA_MISC_OUT, misc);1059 WREG8(MGA_MISC_OUT, misc);
1030}1060}
1031 1061
@@ -1234,12 +1264,13 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, · 202 unmodified lines
1234 const struct drm_display_mode *mode,1264 const struct drm_display_mode *mode,
1235 const struct drm_framebuffer *fb)1265 const struct drm_framebuffer *fb)
1236{1266{
1267 u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1237 unsigned int hiprilvl;1268 unsigned int hiprilvl;
1238 u8 crtcext6;1269 u8 crtcext6;
1239 1270
1240 if (mdev->unique_rev_id >= 0x04) {1271 if (unique_rev_id >= 0x04) {
1241 hiprilvl = 0;1272 hiprilvl = 0;
1242 } else if (mdev->unique_rev_id >= 0x02) {1273 } else if (unique_rev_id >= 0x02) {
1243 unsigned int bpp;1274 unsigned int bpp;
1244 unsigned long mb;1275 unsigned long mb;
1245 1276
@@ -1264,7 +1295,7 @@ static void mgag200_g200se_set_hiprilvl(struct mga_device *mdev, · 18 unmodified lines
1264 else1295 else
1265 hiprilvl = 5;1296 hiprilvl = 5;
1266 1297
1267 } else if (mdev->unique_rev_id >= 0x01) {1298 } else if (unique_rev_id >= 0x01) {
1268 hiprilvl = 3;1299 hiprilvl = 3;
1269 } else {1300 } else {
1270 hiprilvl = 4;1301 hiprilvl = 4;
@@ -1388,7 +1419,9 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, · 117 unmodified lines
1388 int bpp = 32;1419 int bpp = 32;
1389 1420
1390 if (IS_G200_SE(mdev)) {1421 if (IS_G200_SE(mdev)) {
1391 if (mdev->unique_rev_id == 0x01) {1422 u32 unique_rev_id = mdev->model.g200se.unique_rev_id;
1423
1424 if (unique_rev_id == 0x01) {
1392 if (mode->hdisplay > 1600)1425 if (mode->hdisplay > 1600)
1393 return MODE_VIRTUAL_X;1426 return MODE_VIRTUAL_X;
1394 if (mode->vdisplay > 1200)1427 if (mode->vdisplay > 1200)
@@ -1396,7 +1429,7 @@ static enum drm_mode_status mga_vga_mode_valid(struct drm_connector *connector, · 1 unmodified line
1396 if (mga_vga_calculate_mode_bandwidth(mode, bpp)1429 if (mga_vga_calculate_mode_bandwidth(mode, bpp)
1397 > (24400 * 1024))1430 > (24400 * 1024))
1398 return MODE_BANDWIDTH;1431 return MODE_BANDWIDTH;
1399 } else if (mdev->unique_rev_id == 0x02) {1432 } else if (unique_rev_id == 0x02) {
1400 if (mode->hdisplay > 1920)1433 if (mode->hdisplay > 1920)
1401 return MODE_VIRTUAL_X;1434 return MODE_VIRTUAL_X;
1402 if (mode->vdisplay > 1200)1435 if (mode->vdisplay > 1200)
drivers/gpu/drm/mgag200/mgag200_reg.h+4−0
@@ -256,6 +256,8 @@ · 255 unmodified lines
256#define MGAREG_CRTCEXT1_VSYNCOFF BIT(5)256#define MGAREG_CRTCEXT1_VSYNCOFF BIT(5)
257#define MGAREG_CRTCEXT1_HSYNCOFF BIT(4)257#define MGAREG_CRTCEXT1_HSYNCOFF BIT(4)
258 258
259#define MGAREG_CRTCEXT3_MGAMODE BIT(7)
260
259/* Cursor X and Y position */261/* Cursor X and Y position */
260#define MGA_CURPOSXL 0x3c0c262#define MGA_CURPOSXL 0x3c0c
261#define MGA_CURPOSXH 0x3c0d263#define MGA_CURPOSXH 0x3c0d
@@ -282,6 +284,8 @@ · 20 unmodified lines
282#define PCI_MGA_OPTION2 0x50284#define PCI_MGA_OPTION2 0x50
283#define PCI_MGA_OPTION3 0x54285#define PCI_MGA_OPTION3 0x54
284 286
287#define PCI_MGA_OPTION_HARDPWMSK BIT(14)
288
285#define RAMDAC_OFFSET 0x3c00289#define RAMDAC_OFFSET 0x3c00
286 290
287/* TVP3026 direct registers */291/* TVP3026 direct registers */
drivers/gpu/drm/msm/disp/mdp4/mdp4_lvds_connector.c+1−6
@@ -50,14 +50,9 @@ static int mdp4_lvds_connector_get_modes(struct drm_connector *connector) · 49 unmodified lines
50 struct drm_panel *panel = mdp4_lvds_connector->panel;50 struct drm_panel *panel = mdp4_lvds_connector->panel;
51 int ret = 0;51 int ret = 0;
52 52
53 if (panel) {53 if (panel)
54 drm_panel_attach(panel, connector);
55
56 ret = drm_panel_get_modes(panel, connector);54 ret = drm_panel_get_modes(panel, connector);
57 55
58 drm_panel_detach(panel);
59 }
60
61 return ret;56 return ret;
62}57}
63 58
drivers/gpu/drm/msm/dsi/dsi_manager.c+0−1
@@ -328,7 +328,6 @@ static int dsi_mgr_connector_get_modes(struct drm_connector *connector) · 327 unmodified lines
328 * In dual DSI mode, we have one connector that can be328 * In dual DSI mode, we have one connector that can be
329 * attached to the drm_panel.329 * attached to the drm_panel.
330 */330 */
331 drm_panel_attach(panel, connector);
332 num = drm_panel_get_modes(panel, connector);331 num = drm_panel_get_modes(panel, connector);
333 if (!num)332 if (!num)
334 return 0;333 return 0;
drivers/gpu/drm/mxsfb/Kconfig+5−3
@@ -5,7 +5,7 @@ config DRM_MXS · 4 unmodified lines
5 Choose this option to select drivers for MXS FB devices5 Choose this option to select drivers for MXS FB devices
6 6
7config DRM_MXSFB7config DRM_MXSFB
8 tristate "i.MX23/i.MX28/i.MX6SX MXSFB LCD controller"8 tristate "i.MX (e)LCDIF LCD controller"
9 depends on DRM && OF9 depends on DRM && OF
10 depends on COMMON_CLK10 depends on COMMON_CLK
11 select DRM_MXS11 select DRM_MXS
@@ -13,8 +13,10 @@ config DRM_MXSFB · 1 unmodified line
13 select DRM_KMS_FB_HELPER13 select DRM_KMS_FB_HELPER
14 select DRM_KMS_CMA_HELPER14 select DRM_KMS_CMA_HELPER
15 select DRM_PANEL15 select DRM_PANEL
16 select DRM_PANEL_BRIDGE
16 help17 help
17 Choose this option if you have an i.MX23/i.MX28/i.MX6SX MXSFB18 Choose this option if you have an LCDIF or eLCDIF LCD controller.
18 LCD controller.19 Those devices are found in various i.MX SoC (including i.MX23,
20 i.MX28, i.MX6SX, i.MX7 and i.MX8M).
19 21
20 If M is selected the module will be called mxsfb.22 If M is selected the module will be called mxsfb.
drivers/gpu/drm/mxsfb/Makefile+1−1
@@ -1,3 +1,3 @@
1# SPDX-License-Identifier: GPL-2.0-only1# SPDX-License-Identifier: GPL-2.0-only
2mxsfb-y := mxsfb_drv.o mxsfb_crtc.o mxsfb_out.o2mxsfb-y := mxsfb_drv.o mxsfb_kms.o
3obj-$(CONFIG_DRM_MXSFB) += mxsfb.o3obj-$(CONFIG_DRM_MXSFB) += mxsfb.o
drivers/gpu/drm/mxsfb/mxsfb_crtc.c+0−343
@@ -1,343 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Marek Vasut <marex@denx.de>
4 *
5 * This code is based on drivers/video/fbdev/mxsfb.c :
6 * Copyright (C) 2010 Juergen Beisert, Pengutronix
7 * Copyright (C) 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved.
9 */
10
11#include <linux/clk.h>
12#include <linux/iopoll.h>
13#include <linux/of_graph.h>
14#include <linux/platform_data/simplefb.h>
15
16#include <video/videomode.h>
17
18#include <drm/drm_atomic_helper.h>
19#include <drm/drm_crtc.h>
20#include <drm/drm_fb_cma_helper.h>
21#include <drm/drm_fb_helper.h>
22#include <drm/drm_gem_cma_helper.h>
23#include <drm/drm_of.h>
24#include <drm/drm_plane_helper.h>
25#include <drm/drm_probe_helper.h>
26#include <drm/drm_simple_kms_helper.h>
27#include <drm/drm_vblank.h>
28
29#include "mxsfb_drv.h"
30#include "mxsfb_regs.h"
31
32#define MXS_SET_ADDR 0x4
33#define MXS_CLR_ADDR 0x8
34#define MODULE_CLKGATE BIT(30)
35#define MODULE_SFTRST BIT(31)
36/* 1 second delay should be plenty of time for block reset */
37#define RESET_TIMEOUT 1000000
38
39static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val)
40{
41 return (val & mxsfb->devdata->hs_wdth_mask) <<
42 mxsfb->devdata->hs_wdth_shift;
43}
44
45/* Setup the MXSFB registers for decoding the pixels out of the framebuffer */
46static int mxsfb_set_pixel_fmt(struct mxsfb_drm_private *mxsfb)
47{
48 struct drm_crtc *crtc = &mxsfb->pipe.crtc;
49 struct drm_device *drm = crtc->dev;
50 const u32 format = crtc->primary->state->fb->format->format;
51 u32 ctrl, ctrl1;
52
53 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER;
54
55 /*
56 * WARNING: The bus width, CTRL_SET_BUS_WIDTH(), is configured to
57 * match the selected mode here. This differs from the original
58 * MXSFB driver, which had the option to configure the bus width
59 * to arbitrary value. This limitation should not pose an issue.
60 */
61
62 /* CTRL1 contains IRQ config and status bits, preserve those. */
63 ctrl1 = readl(mxsfb->base + LCDC_CTRL1);
64 ctrl1 &= CTRL1_CUR_FRAME_DONE_IRQ_EN | CTRL1_CUR_FRAME_DONE_IRQ;
65
66 switch (format) {
67 case DRM_FORMAT_RGB565:
68 dev_dbg(drm->dev, "Setting up RGB565 mode\n");
69 ctrl |= CTRL_SET_WORD_LENGTH(0);
70 ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
71 break;
72 case DRM_FORMAT_XRGB8888:
73 dev_dbg(drm->dev, "Setting up XRGB8888 mode\n");
74 ctrl |= CTRL_SET_WORD_LENGTH(3);
75 /* Do not use packed pixels = one pixel per word instead. */
76 ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7);
77 break;
78 default:
79 dev_err(drm->dev, "Unhandled pixel format %08x\n", format);
80 return -EINVAL;
81 }
82
83 writel(ctrl1, mxsfb->base + LCDC_CTRL1);
84 writel(ctrl, mxsfb->base + LCDC_CTRL);
85
86 return 0;
87}
88
89static void mxsfb_set_bus_fmt(struct mxsfb_drm_private *mxsfb)
90{
91 struct drm_crtc *crtc = &mxsfb->pipe.crtc;
92 struct drm_device *drm = crtc->dev;
93 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
94 u32 reg;
95
96 reg = readl(mxsfb->base + LCDC_CTRL);
97
98 if (mxsfb->connector->display_info.num_bus_formats)
99 bus_format = mxsfb->connector->display_info.bus_formats[0];
100
101 DRM_DEV_DEBUG_DRIVER(drm->dev, "Using bus_format: 0x%08X\n",
102 bus_format);
103
104 reg &= ~CTRL_BUS_WIDTH_MASK;
105 switch (bus_format) {
106 case MEDIA_BUS_FMT_RGB565_1X16:
107 reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_16BIT);
108 break;
109 case MEDIA_BUS_FMT_RGB666_1X18:
110 reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_18BIT);
111 break;
112 case MEDIA_BUS_FMT_RGB888_1X24:
113 reg |= CTRL_SET_BUS_WIDTH(STMLCDIF_24BIT);
114 break;
115 default:
116 dev_err(drm->dev, "Unknown media bus format %d\n", bus_format);
117 break;
118 }
119 writel(reg, mxsfb->base + LCDC_CTRL);
120}
121
122static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
123{
124 u32 reg;
125
126 if (mxsfb->clk_disp_axi)
127 clk_prepare_enable(mxsfb->clk_disp_axi);
128 clk_prepare_enable(mxsfb->clk);
129
130 /* If it was disabled, re-enable the mode again */
131 writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET);
132
133 /* Enable the SYNC signals first, then the DMA engine */
134 reg = readl(mxsfb->base + LCDC_VDCTRL4);
135 reg |= VDCTRL4_SYNC_SIGNALS_ON;
136 writel(reg, mxsfb->base + LCDC_VDCTRL4);
137
138 writel(CTRL_RUN, mxsfb->base + LCDC_CTRL + REG_SET);
139}
140
141static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
142{
143 u32 reg;
144
145 /*
146 * Even if we disable the controller here, it will still continue
147 * until its FIFOs are running out of data
148 */
149 writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_CLR);
150
151 readl_poll_timeout(mxsfb->base + LCDC_CTRL, reg, !(reg & CTRL_RUN),
152 0, 1000);
153
154 reg = readl(mxsfb->base + LCDC_VDCTRL4);
155 reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
156 writel(reg, mxsfb->base + LCDC_VDCTRL4);
157
158 clk_disable_unprepare(mxsfb->clk);
159 if (mxsfb->clk_disp_axi)
160 clk_disable_unprepare(mxsfb->clk_disp_axi);
161}
162
163/*
164 * Clear the bit and poll it cleared. This is usually called with
165 * a reset address and mask being either SFTRST(bit 31) or CLKGATE
166 * (bit 30).
167 */
168static int clear_poll_bit(void __iomem *addr, u32 mask)
169{
170 u32 reg;
171
172 writel(mask, addr + MXS_CLR_ADDR);
173 return readl_poll_timeout(addr, reg, !(reg & mask), 0, RESET_TIMEOUT);
174}
175
176static int mxsfb_reset_block(void __iomem *reset_addr)
177{
178 int ret;
179
180 ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
181 if (ret)
182 return ret;
183
184 writel(MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
185
186 ret = clear_poll_bit(reset_addr, MODULE_SFTRST);
187 if (ret)
188 return ret;
189
190 return clear_poll_bit(reset_addr, MODULE_CLKGATE);
191}
192
193static dma_addr_t mxsfb_get_fb_paddr(struct mxsfb_drm_private *mxsfb)
194{
195 struct drm_framebuffer *fb = mxsfb->pipe.plane.state->fb;
196 struct drm_gem_cma_object *gem;
197
198 if (!fb)
199 return 0;
200
201 gem = drm_fb_cma_get_gem_obj(fb, 0);
202 if (!gem)
203 return 0;
204
205 return gem->paddr;
206}
207
208static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
209{
210 struct drm_device *drm = mxsfb->pipe.crtc.dev;
211 struct drm_display_mode *m = &mxsfb->pipe.crtc.state->adjusted_mode;
212 u32 bus_flags = mxsfb->connector->display_info.bus_flags;
213 u32 vdctrl0, vsync_pulse_len, hsync_pulse_len;
214 int err;
215
216 /*
217 * It seems, you can't re-program the controller if it is still
218 * running. This may lead to shifted pictures (FIFO issue?), so
219 * first stop the controller and drain its FIFOs.
220 */
221
222 /* Mandatory eLCDIF reset as per the Reference Manual */
223 err = mxsfb_reset_block(mxsfb->base);
224 if (err)
225 return;
226
227 /* Clear the FIFOs */
228 writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET);
229
230 err = mxsfb_set_pixel_fmt(mxsfb);
231 if (err)
232 return;
233
234 clk_set_rate(mxsfb->clk, m->crtc_clock * 1000);
235
236 if (mxsfb->bridge && mxsfb->bridge->timings)
237 bus_flags = mxsfb->bridge->timings->input_bus_flags;
238
239 DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
240 m->crtc_clock,
241 (int)(clk_get_rate(mxsfb->clk) / 1000));
242 DRM_DEV_DEBUG_DRIVER(drm->dev, "Connector bus_flags: 0x%08X\n",
243 bus_flags);
244 DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags);
245
246 writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) |
247 TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay),
248 mxsfb->base + mxsfb->devdata->transfer_count);
249
250 vsync_pulse_len = m->crtc_vsync_end - m->crtc_vsync_start;
251
252 vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* Always in DOTCLOCK mode */
253 VDCTRL0_VSYNC_PERIOD_UNIT |
254 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
255 VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len);
256 if (m->flags & DRM_MODE_FLAG_PHSYNC)
257 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
258 if (m->flags & DRM_MODE_FLAG_PVSYNC)
259 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
260 /* Make sure Data Enable is high active by default */
261 if (!(bus_flags & DRM_BUS_FLAG_DE_LOW))
262 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
263 /*
264 * DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric,
265 * controllers VDCTRL0_DOTCLK is display centric.
266 * Drive on positive edge -> display samples on falling edge
267 * DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
268 */
269 if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
270 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
271
272 writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0);
273
274 mxsfb_set_bus_fmt(mxsfb);
275
276 /* Frame length in lines. */
277 writel(m->crtc_vtotal, mxsfb->base + LCDC_VDCTRL1);
278
279 /* Line length in units of clocks or pixels. */
280 hsync_pulse_len = m->crtc_hsync_end - m->crtc_hsync_start;
281 writel(set_hsync_pulse_width(mxsfb, hsync_pulse_len) |
282 VDCTRL2_SET_HSYNC_PERIOD(m->crtc_htotal),
283 mxsfb->base + LCDC_VDCTRL2);
284
285 writel(SET_HOR_WAIT_CNT(m->crtc_htotal - m->crtc_hsync_start) |
286 SET_VERT_WAIT_CNT(m->crtc_vtotal - m->crtc_vsync_start),
287 mxsfb->base + LCDC_VDCTRL3);
288
289 writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay),
290 mxsfb->base + LCDC_VDCTRL4);
291}
292
293void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb)
294{
295 dma_addr_t paddr;
296
297 mxsfb_enable_axi_clk(mxsfb);
298 mxsfb_crtc_mode_set_nofb(mxsfb);
299
300 /* Write cur_buf as well to avoid an initial corrupt frame */
301 paddr = mxsfb_get_fb_paddr(mxsfb);
302 if (paddr) {
303 writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf);
304 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
305 }
306
307 mxsfb_enable_controller(mxsfb);
308}
309
310void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb)
311{
312 mxsfb_disable_controller(mxsfb);
313 mxsfb_disable_axi_clk(mxsfb);
314}
315
316void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
317 struct drm_plane_state *state)
318{
319 struct drm_simple_display_pipe *pipe = &mxsfb->pipe;
320 struct drm_crtc *crtc = &pipe->crtc;
321 struct drm_pending_vblank_event *event;
322 dma_addr_t paddr;
323
324 spin_lock_irq(&crtc->dev->event_lock);
325 event = crtc->state->event;
326 if (event) {
327 crtc->state->event = NULL;
328
329 if (drm_crtc_vblank_get(crtc) == 0) {
330 drm_crtc_arm_vblank_event(crtc, event);
331 } else {
332 drm_crtc_send_vblank_event(crtc, event);
333 }
334 }
335 spin_unlock_irq(&crtc->dev->event_lock);
336
337 paddr = mxsfb_get_fb_paddr(mxsfb);
338 if (paddr) {
339 mxsfb_enable_axi_clk(mxsfb);
340 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
341 mxsfb_disable_axi_clk(mxsfb);
342 }
343}
drivers/gpu/drm/mxsfb/mxsfb_drv.c+77−175
@@ -9,30 +9,24 @@ · 8 unmodified lines
9 */9 */
10 10
11#include <linux/clk.h>11#include <linux/clk.h>
12#include <linux/component.h>
13#include <linux/dma-mapping.h>12#include <linux/dma-mapping.h>
14#include <linux/list.h>13#include <linux/io.h>
15#include <linux/module.h>14#include <linux/module.h>
16#include <linux/of_device.h>15#include <linux/of_device.h>
17#include <linux/of_graph.h>16#include <linux/platform_device.h>
18#include <linux/of_reserved_mem.h>
19#include <linux/pm_runtime.h>17#include <linux/pm_runtime.h>
20#include <linux/dma-resv.h>
21#include <linux/spinlock.h>
22 18
23#include <drm/drm_atomic.h>
24#include <drm/drm_atomic_helper.h>19#include <drm/drm_atomic_helper.h>
25#include <drm/drm_crtc.h>20#include <drm/drm_bridge.h>
21#include <drm/drm_connector.h>
26#include <drm/drm_drv.h>22#include <drm/drm_drv.h>
27#include <drm/drm_fb_cma_helper.h>
28#include <drm/drm_fb_helper.h>23#include <drm/drm_fb_helper.h>
29#include <drm/drm_gem_cma_helper.h>24#include <drm/drm_gem_cma_helper.h>
30#include <drm/drm_gem_framebuffer_helper.h>25#include <drm/drm_gem_framebuffer_helper.h>
31#include <drm/drm_irq.h>26#include <drm/drm_irq.h>
27#include <drm/drm_mode_config.h>
32#include <drm/drm_of.h>28#include <drm/drm_of.h>
33#include <drm/drm_panel.h>
34#include <drm/drm_probe_helper.h>29#include <drm/drm_probe_helper.h>
35#include <drm/drm_simple_kms_helper.h>
36#include <drm/drm_vblank.h>30#include <drm/drm_vblank.h>
37 31
38#include "mxsfb_drv.h"32#include "mxsfb_drv.h"
@@ -41,6 +35,11 @@ · 2 unmodified lines
41enum mxsfb_devtype {35enum mxsfb_devtype {
42 MXSFB_V3,36 MXSFB_V3,
43 MXSFB_V4,37 MXSFB_V4,
38 /*
39 * Starting at i.MX6 the hardware version register is gone, use the
40 * i.MX family number as the version.
41 */
42 MXSFB_V6,
44};43};
45 44
46static const struct mxsfb_devdata mxsfb_devdata[] = {45static const struct mxsfb_devdata mxsfb_devdata[] = {
@@ -48,38 +47,28 @@ static const struct mxsfb_devdata mxsfb_devdata[] = { · 1 unmodified line
48 .transfer_count = LCDC_V3_TRANSFER_COUNT,47 .transfer_count = LCDC_V3_TRANSFER_COUNT,
49 .cur_buf = LCDC_V3_CUR_BUF,48 .cur_buf = LCDC_V3_CUR_BUF,
50 .next_buf = LCDC_V3_NEXT_BUF,49 .next_buf = LCDC_V3_NEXT_BUF,
51 .debug0 = LCDC_V3_DEBUG0,
52 .hs_wdth_mask = 0xff,50 .hs_wdth_mask = 0xff,
53 .hs_wdth_shift = 24,51 .hs_wdth_shift = 24,
54 .ipversion = 3,52 .has_overlay = false,
55 },53 },
56 [MXSFB_V4] = {54 [MXSFB_V4] = {
57 .transfer_count = LCDC_V4_TRANSFER_COUNT,55 .transfer_count = LCDC_V4_TRANSFER_COUNT,
58 .cur_buf = LCDC_V4_CUR_BUF,56 .cur_buf = LCDC_V4_CUR_BUF,
59 .next_buf = LCDC_V4_NEXT_BUF,57 .next_buf = LCDC_V4_NEXT_BUF,
60 .debug0 = LCDC_V4_DEBUG0,
61 .hs_wdth_mask = 0x3fff,58 .hs_wdth_mask = 0x3fff,
62 .hs_wdth_shift = 18,59 .hs_wdth_shift = 18,
63 .ipversion = 4,60 .has_overlay = false,
61 },
62 [MXSFB_V6] = {
63 .transfer_count = LCDC_V4_TRANSFER_COUNT,
64 .cur_buf = LCDC_V4_CUR_BUF,
65 .next_buf = LCDC_V4_NEXT_BUF,
66 .hs_wdth_mask = 0x3fff,
67 .hs_wdth_shift = 18,
68 .has_overlay = true,
64 },69 },
65};70};
66 71
67static const uint32_t mxsfb_formats[] = {
68 DRM_FORMAT_XRGB8888,
69 DRM_FORMAT_RGB565
70};
71
72static const uint64_t mxsfb_modifiers[] = {
73 DRM_FORMAT_MOD_LINEAR,
74 DRM_FORMAT_MOD_INVALID
75};
76
77static struct mxsfb_drm_private *
78drm_pipe_to_mxsfb_drm_private(struct drm_simple_display_pipe *pipe)
79{
80 return container_of(pipe, struct mxsfb_drm_private, pipe);
81}
82
83void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)72void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb)
84{73{
85 if (mxsfb->clk_axi)74 if (mxsfb->clk_axi)
@@ -102,101 +91,51 @@ static const struct drm_mode_config_helper_funcs mxsfb_mode_config_helpers = { · 16 unmodified lines
102 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,91 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
103};92};
104 93
105static void mxsfb_pipe_enable(struct drm_simple_display_pipe *pipe,94static int mxsfb_attach_bridge(struct mxsfb_drm_private *mxsfb)
106 struct drm_crtc_state *crtc_state,
107 struct drm_plane_state *plane_state)
108{95{
109 struct drm_connector *connector;96 struct drm_device *drm = mxsfb->drm;
110 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);97 struct drm_connector_list_iter iter;
111 struct drm_device *drm = pipe->plane.dev;98 struct drm_panel *panel;
112 99 struct drm_bridge *bridge;
113 if (!mxsfb->connector) {100 int ret;
114 list_for_each_entry(connector,
115 &drm->mode_config.connector_list,
116 head)
117 if (connector->encoder == &mxsfb->pipe.encoder) {
118 mxsfb->connector = connector;
119 break;
120 }
121 }
122
123 if (!mxsfb->connector) {
124 dev_warn(drm->dev, "No connector attached, using default\n");
125 mxsfb->connector = &mxsfb->panel_connector;
126 }
127
128 pm_runtime_get_sync(drm->dev);
129 drm_panel_prepare(mxsfb->panel);
130 mxsfb_crtc_enable(mxsfb);
131 drm_panel_enable(mxsfb->panel);
132}
133 101
134static void mxsfb_pipe_disable(struct drm_simple_display_pipe *pipe)102 ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0, &panel,
135{103 &bridge);
136 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);104 if (ret)
137 struct drm_device *drm = pipe->plane.dev;105 return ret;
138 struct drm_crtc *crtc = &pipe->crtc;
139 struct drm_pending_vblank_event *event;
140
141 drm_panel_disable(mxsfb->panel);
142 mxsfb_crtc_disable(mxsfb);
143 drm_panel_unprepare(mxsfb->panel);
144 pm_runtime_put_sync(drm->dev);
145 106
146 spin_lock_irq(&drm->event_lock);107 if (panel) {
147 event = crtc->state->event;108 bridge = devm_drm_panel_bridge_add_typed(drm->dev, panel,
148 if (event) {109 DRM_MODE_CONNECTOR_DPI);
149 crtc->state->event = NULL;110 if (IS_ERR(bridge))
150 drm_crtc_send_vblank_event(crtc, event);111 return PTR_ERR(bridge);
151 }112 }
152 spin_unlock_irq(&drm->event_lock);
153 113
154 if (mxsfb->connector != &mxsfb->panel_connector)114 if (!bridge)
155 mxsfb->connector = NULL;115 return -ENODEV;
156}
157
158static void mxsfb_pipe_update(struct drm_simple_display_pipe *pipe,
159 struct drm_plane_state *plane_state)
160{
161 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
162 116
163 mxsfb_plane_atomic_update(mxsfb, plane_state);117 ret = drm_bridge_attach(&mxsfb->encoder, bridge, NULL, 0);
164}118 if (ret) {
119 DRM_DEV_ERROR(drm->dev,
120 "failed to attach bridge: %d\n", ret);
121 return ret;
122 }
165 123
166static int mxsfb_pipe_enable_vblank(struct drm_simple_display_pipe *pipe)124 mxsfb->bridge = bridge;
167{
168 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
169 125
170 /* Clear and enable VBLANK IRQ */126 /*
171 mxsfb_enable_axi_clk(mxsfb);127 * Get hold of the connector. This is a bit of a hack, until the bridge
172 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);128 * API gives us bus flags and formats.
173 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);129 */
174 mxsfb_disable_axi_clk(mxsfb);130 drm_connector_list_iter_begin(drm, &iter);
131 mxsfb->connector = drm_connector_list_iter_next(&iter);
132 drm_connector_list_iter_end(&iter);
175 133
176 return 0;134 return 0;
177}135}
178 136
179static void mxsfb_pipe_disable_vblank(struct drm_simple_display_pipe *pipe)137static int mxsfb_load(struct drm_device *drm,
180{138 const struct mxsfb_devdata *devdata)
181 struct mxsfb_drm_private *mxsfb = drm_pipe_to_mxsfb_drm_private(pipe);
182
183 /* Disable and clear VBLANK IRQ */
184 mxsfb_enable_axi_clk(mxsfb);
185 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
186 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
187 mxsfb_disable_axi_clk(mxsfb);
188}
189
190static struct drm_simple_display_pipe_funcs mxsfb_funcs = {
191 .enable = mxsfb_pipe_enable,
192 .disable = mxsfb_pipe_disable,
193 .update = mxsfb_pipe_update,
194 .prepare_fb = drm_gem_fb_simple_display_pipe_prepare_fb,
195 .enable_vblank = mxsfb_pipe_enable_vblank,
196 .disable_vblank = mxsfb_pipe_disable_vblank,
197};
198
199static int mxsfb_load(struct drm_device *drm)
200{139{
201 struct platform_device *pdev = to_platform_device(drm->dev);140 struct platform_device *pdev = to_platform_device(drm->dev);
202 struct mxsfb_drm_private *mxsfb;141 struct mxsfb_drm_private *mxsfb;
@@ -207,8 +146,9 @@ static int mxsfb_load(struct drm_device *drm) · 4 unmodified lines
207 if (!mxsfb)146 if (!mxsfb)
208 return -ENOMEM;147 return -ENOMEM;
209 148
149 mxsfb->drm = drm;
210 drm->dev_private = mxsfb;150 drm->dev_private = mxsfb;
211 mxsfb->devdata = &mxsfb_devdata[pdev->id_entry->driver_data];151 mxsfb->devdata = devdata;
212 152
213 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);153 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
214 mxsfb->base = devm_ioremap_resource(drm->dev, res);154 mxsfb->base = devm_ioremap_resource(drm->dev, res);
@@ -233,50 +173,28 @@ static int mxsfb_load(struct drm_device *drm) · 18 unmodified lines
233 173
234 pm_runtime_enable(drm->dev);174 pm_runtime_enable(drm->dev);
235 175
236 ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
237 if (ret < 0) {
238 dev_err(drm->dev, "Failed to initialise vblank\n");
239 goto err_vblank;
240 }
241
242 /* Modeset init */176 /* Modeset init */
243 drm_mode_config_init(drm);177 drm_mode_config_init(drm);
244 178
245 ret = mxsfb_create_output(drm);179 ret = mxsfb_kms_init(mxsfb);
246 if (ret < 0) {180 if (ret < 0) {
247 dev_err(drm->dev, "Failed to create outputs\n");181 dev_err(drm->dev, "Failed to initialize KMS pipeline\n");
248 goto err_vblank;182 goto err_vblank;
249 }183 }
250 184
251 ret = drm_simple_display_pipe_init(drm, &mxsfb->pipe, &mxsfb_funcs,185 ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
252 mxsfb_formats, ARRAY_SIZE(mxsfb_formats),
253 mxsfb_modifiers, mxsfb->connector);
254 if (ret < 0) {186 if (ret < 0) {
255 dev_err(drm->dev, "Cannot setup simple display pipe\n");187 dev_err(drm->dev, "Failed to initialise vblank\n");
256 goto err_vblank;188 goto err_vblank;
257 }189 }
258 190
259 /*191 /* Start with vertical blanking interrupt reporting disabled. */
260 * Attach panel only if there is one.192 drm_crtc_vblank_off(&mxsfb->crtc);
261 * If there is no panel attach, it must be a bridge. In this case, we
262 * need a reference to its connector for a proper initialization.
263 * We will do this check in pipe->enable(), since the connector won't
264 * be attached to an encoder until then.
265 */
266 193
267 if (mxsfb->panel) {194 ret = mxsfb_attach_bridge(mxsfb);
268 ret = drm_panel_attach(mxsfb->panel, mxsfb->connector);195 if (ret) {
269 if (ret) {196 dev_err(drm->dev, "Cannot connect bridge: %d\n", ret);
270 dev_err(drm->dev, "Cannot connect panel: %d\n", ret);197 goto err_vblank;
271 goto err_vblank;
272 }
273 } else if (mxsfb->bridge) {
274 ret = drm_simple_display_pipe_attach_bridge(&mxsfb->pipe,
275 mxsfb->bridge);
276 if (ret) {
277 dev_err(drm->dev, "Cannot connect bridge: %d\n", ret);
278 goto err_vblank;
279 }
280 }198 }
281 199
282 drm->mode_config.min_width = MXSFB_MIN_XRES;200 drm->mode_config.min_width = MXSFB_MIN_XRES;
@@ -294,7 +212,7 @@ static int mxsfb_load(struct drm_device *drm) · 11 unmodified lines
294 212
295 if (ret < 0) {213 if (ret < 0) {
296 dev_err(drm->dev, "Failed to install IRQ handler\n");214 dev_err(drm->dev, "Failed to install IRQ handler\n");
297 goto err_irq;215 goto err_vblank;
298 }216 }
299 217
300 drm_kms_helper_poll_init(drm);218 drm_kms_helper_poll_init(drm);
@@ -305,8 +223,6 @@ static int mxsfb_load(struct drm_device *drm) · 4 unmodified lines
305 223
306 return 0;224 return 0;
307 225
308err_irq:
309 drm_panel_detach(mxsfb->panel);
310err_vblank:226err_vblank:
311 pm_runtime_disable(drm->dev);227 pm_runtime_disable(drm->dev);
312 228
@@ -327,11 +243,13 @@ static void mxsfb_unload(struct drm_device *drm) · 14 unmodified lines
327 pm_runtime_disable(drm->dev);243 pm_runtime_disable(drm->dev);
328}244}
329 245
330static void mxsfb_irq_preinstall(struct drm_device *drm)246static void mxsfb_irq_disable(struct drm_device *drm)
331{247{
332 struct mxsfb_drm_private *mxsfb = drm->dev_private;248 struct mxsfb_drm_private *mxsfb = drm->dev_private;
333 249
334 mxsfb_pipe_disable_vblank(&mxsfb->pipe);250 mxsfb_enable_axi_clk(mxsfb);
251 mxsfb->crtc.funcs->disable_vblank(&mxsfb->crtc);
252 mxsfb_disable_axi_clk(mxsfb);
335}253}
336 254
337static irqreturn_t mxsfb_irq_handler(int irq, void *data)255static irqreturn_t mxsfb_irq_handler(int irq, void *data)
@@ -340,17 +258,13 @@ static irqreturn_t mxsfb_irq_handler(int irq, void *data) · 2 unmodified lines
340 struct mxsfb_drm_private *mxsfb = drm->dev_private;258 struct mxsfb_drm_private *mxsfb = drm->dev_private;
341 u32 reg;259 u32 reg;
342 260
343 mxsfb_enable_axi_clk(mxsfb);
344
345 reg = readl(mxsfb->base + LCDC_CTRL1);261 reg = readl(mxsfb->base + LCDC_CTRL1);
346 262
347 if (reg & CTRL1_CUR_FRAME_DONE_IRQ)263 if (reg & CTRL1_CUR_FRAME_DONE_IRQ)
348 drm_crtc_handle_vblank(&mxsfb->pipe.crtc);264 drm_crtc_handle_vblank(&mxsfb->crtc);
349 265
350 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);266 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
351 267
352 mxsfb_disable_axi_clk(mxsfb);
353
354 return IRQ_HANDLED;268 return IRQ_HANDLED;
355}269}
356 270
@@ -359,8 +273,8 @@ DEFINE_DRM_GEM_CMA_FOPS(fops); · 2 unmodified lines
359static struct drm_driver mxsfb_driver = {273static struct drm_driver mxsfb_driver = {
360 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,274 .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC,
361 .irq_handler = mxsfb_irq_handler,275 .irq_handler = mxsfb_irq_handler,
362 .irq_preinstall = mxsfb_irq_preinstall,276 .irq_preinstall = mxsfb_irq_disable,
363 .irq_uninstall = mxsfb_irq_preinstall,277 .irq_uninstall = mxsfb_irq_disable,
364 DRM_GEM_CMA_DRIVER_OPS,278 DRM_GEM_CMA_DRIVER_OPS,
365 .fops = &fops,279 .fops = &fops,
366 .name = "mxsfb-drm",280 .name = "mxsfb-drm",
@@ -370,18 +284,10 @@ static struct drm_driver mxsfb_driver = { · 3 unmodified lines
370 .minor = 0,284 .minor = 0,
371};285};
372 286
373static const struct platform_device_id mxsfb_devtype[] = {
374 { .name = "imx23-fb", .driver_data = MXSFB_V3, },
375 { .name = "imx28-fb", .driver_data = MXSFB_V4, },
376 { .name = "imx6sx-fb", .driver_data = MXSFB_V4, },
377 { /* sentinel */ }
378};
379MODULE_DEVICE_TABLE(platform, mxsfb_devtype);
380
381static const struct of_device_id mxsfb_dt_ids[] = {287static const struct of_device_id mxsfb_dt_ids[] = {
382 { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devtype[0], },288 { .compatible = "fsl,imx23-lcdif", .data = &mxsfb_devdata[MXSFB_V3], },
383 { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devtype[1], },289 { .compatible = "fsl,imx28-lcdif", .data = &mxsfb_devdata[MXSFB_V4], },
384 { .compatible = "fsl,imx6sx-lcdif", .data = &mxsfb_devtype[2], },290 { .compatible = "fsl,imx6sx-lcdif", .data = &mxsfb_devdata[MXSFB_V6], },
385 { /* sentinel */ }291 { /* sentinel */ }
386};292};
387MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);293MODULE_DEVICE_TABLE(of, mxsfb_dt_ids);
@@ -396,14 +302,11 @@ static int mxsfb_probe(struct platform_device *pdev) · 8 unmodified lines
396 if (!pdev->dev.of_node)302 if (!pdev->dev.of_node)
397 return -ENODEV;303 return -ENODEV;
398 304
399 if (of_id)
400 pdev->id_entry = of_id->data;
401
402 drm = drm_dev_alloc(&mxsfb_driver, &pdev->dev);305 drm = drm_dev_alloc(&mxsfb_driver, &pdev->dev);
403 if (IS_ERR(drm))306 if (IS_ERR(drm))
404 return PTR_ERR(drm);307 return PTR_ERR(drm);
405 308
406 ret = mxsfb_load(drm);309 ret = mxsfb_load(drm, of_id->data);
407 if (ret)310 if (ret)
408 goto err_free;311 goto err_free;
409 312
@@ -457,7 +360,6 @@ static const struct dev_pm_ops mxsfb_pm_ops = { · 47 unmodified lines
457static struct platform_driver mxsfb_platform_driver = {360static struct platform_driver mxsfb_platform_driver = {
458 .probe = mxsfb_probe,361 .probe = mxsfb_probe,
459 .remove = mxsfb_remove,362 .remove = mxsfb_remove,
460 .id_table = mxsfb_devtype,
461 .driver = {363 .driver = {
462 .name = "mxsfb",364 .name = "mxsfb",
463 .of_match_table = mxsfb_dt_ids,365 .of_match_table = mxsfb_dt_ids,
drivers/gpu/drm/mxsfb/mxsfb_drv.h+26−16
@@ -8,14 +8,20 @@ · 7 unmodified lines
8#ifndef __MXSFB_DRV_H__8#ifndef __MXSFB_DRV_H__
9#define __MXSFB_DRV_H__9#define __MXSFB_DRV_H__
10 10
11#include <drm/drm_crtc.h>
12#include <drm/drm_device.h>
13#include <drm/drm_encoder.h>
14#include <drm/drm_plane.h>
15
16struct clk;
17
11struct mxsfb_devdata {18struct mxsfb_devdata {
12 unsigned int transfer_count;19 unsigned int transfer_count;
13 unsigned int cur_buf;20 unsigned int cur_buf;
14 unsigned int next_buf;21 unsigned int next_buf;
15 unsigned int debug0;22 unsigned int hs_wdth_mask;
16 unsigned int hs_wdth_mask;23 unsigned int hs_wdth_shift;
17 unsigned int hs_wdth_shift;24 bool has_overlay;
18 unsigned int ipversion;
19};25};
20 26
21struct mxsfb_drm_private {27struct mxsfb_drm_private {
@@ -26,22 +32,26 @@ struct mxsfb_drm_private { · 4 unmodified lines
26 struct clk *clk_axi;32 struct clk *clk_axi;
27 struct clk *clk_disp_axi;33 struct clk *clk_disp_axi;
28 34
29 struct drm_simple_display_pipe pipe;35 struct drm_device *drm;
30 struct drm_connector panel_connector;36 struct {
37 struct drm_plane primary;
38 struct drm_plane overlay;
39 } planes;
40 struct drm_crtc crtc;
41 struct drm_encoder encoder;
31 struct drm_connector *connector;42 struct drm_connector *connector;
32 struct drm_panel *panel;
33 struct drm_bridge *bridge;43 struct drm_bridge *bridge;
34};44};
35 45
36int mxsfb_setup_crtc(struct drm_device *dev);46static inline struct mxsfb_drm_private *
37int mxsfb_create_output(struct drm_device *dev);47to_mxsfb_drm_private(struct drm_device *drm)
48{
49 return drm->dev_private;
50}
38 51
39void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb);52void mxsfb_enable_axi_clk(struct mxsfb_drm_private *mxsfb);
40void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb);53void mxsfb_disable_axi_clk(struct mxsfb_drm_private *mxsfb);
41 54
42void mxsfb_crtc_enable(struct mxsfb_drm_private *mxsfb);55int mxsfb_kms_init(struct mxsfb_drm_private *mxsfb);
43void mxsfb_crtc_disable(struct mxsfb_drm_private *mxsfb);
44void mxsfb_plane_atomic_update(struct mxsfb_drm_private *mxsfb,
45 struct drm_plane_state *state);
46 56
47#endif /* __MXSFB_DRV_H__ */57#endif /* __MXSFB_DRV_H__ */
drivers/gpu/drm/mxsfb/mxsfb_kms.c+571−0
@@ -0,0 +1,571 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Marek Vasut <marex@denx.de>
4 *
5 * This code is based on drivers/video/fbdev/mxsfb.c :
6 * Copyright (C) 2010 Juergen Beisert, Pengutronix
7 * Copyright (C) 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
8 * Copyright (C) 2008 Embedded Alley Solutions, Inc All Rights Reserved.
9 */
10
11#include <linux/clk.h>
12#include <linux/io.h>
13#include <linux/iopoll.h>
14#include <linux/pm_runtime.h>
15#include <linux/spinlock.h>
16
17#include <drm/drm_atomic.h>
18#include <drm/drm_atomic_helper.h>
19#include <drm/drm_bridge.h>
20#include <drm/drm_crtc.h>
21#include <drm/drm_encoder.h>
22#include <drm/drm_fb_cma_helper.h>
23#include <drm/drm_fourcc.h>
24#include <drm/drm_gem_cma_helper.h>
25#include <drm/drm_plane.h>
26#include <drm/drm_plane_helper.h>
27#include <drm/drm_vblank.h>
28
29#include "mxsfb_drv.h"
30#include "mxsfb_regs.h"
31
32/* 1 second delay should be plenty of time for block reset */
33#define RESET_TIMEOUT 1000000
34
35/* -----------------------------------------------------------------------------
36 * CRTC
37 */
38
39static u32 set_hsync_pulse_width(struct mxsfb_drm_private *mxsfb, u32 val)
40{
41 return (val & mxsfb->devdata->hs_wdth_mask) <<
42 mxsfb->devdata->hs_wdth_shift;
43}
44
45/*
46 * Setup the MXSFB registers for decoding the pixels out of the framebuffer and
47 * outputting them on the bus.
48 */
49static void mxsfb_set_formats(struct mxsfb_drm_private *mxsfb)
50{
51 struct drm_device *drm = mxsfb->drm;
52 const u32 format = mxsfb->crtc.primary->state->fb->format->format;
53 u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
54 u32 ctrl, ctrl1;
55
56 if (mxsfb->connector->display_info.num_bus_formats)
57 bus_format = mxsfb->connector->display_info.bus_formats[0];
58
59 DRM_DEV_DEBUG_DRIVER(drm->dev, "Using bus_format: 0x%08X\n",
60 bus_format);
61
62 ctrl = CTRL_BYPASS_COUNT | CTRL_MASTER;
63
64 /* CTRL1 contains IRQ config and status bits, preserve those. */
65 ctrl1 = readl(mxsfb->base + LCDC_CTRL1);
66 ctrl1 &= CTRL1_CUR_FRAME_DONE_IRQ_EN | CTRL1_CUR_FRAME_DONE_IRQ;
67
68 switch (format) {
69 case DRM_FORMAT_RGB565:
70 dev_dbg(drm->dev, "Setting up RGB565 mode\n");
71 ctrl |= CTRL_WORD_LENGTH_16;
72 ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0xf);
73 break;
74 case DRM_FORMAT_XRGB8888:
75 dev_dbg(drm->dev, "Setting up XRGB8888 mode\n");
76 ctrl |= CTRL_WORD_LENGTH_24;
77 /* Do not use packed pixels = one pixel per word instead. */
78 ctrl1 |= CTRL1_SET_BYTE_PACKAGING(0x7);
79 break;
80 }
81
82 switch (bus_format) {
83 case MEDIA_BUS_FMT_RGB565_1X16:
84 ctrl |= CTRL_BUS_WIDTH_16;
85 break;
86 case MEDIA_BUS_FMT_RGB666_1X18:
87 ctrl |= CTRL_BUS_WIDTH_18;
88 break;
89 case MEDIA_BUS_FMT_RGB888_1X24:
90 ctrl |= CTRL_BUS_WIDTH_24;
91 break;
92 default:
93 dev_err(drm->dev, "Unknown media bus format %d\n", bus_format);
94 break;
95 }
96
97 writel(ctrl1, mxsfb->base + LCDC_CTRL1);
98 writel(ctrl, mxsfb->base + LCDC_CTRL);
99}
100
101static void mxsfb_enable_controller(struct mxsfb_drm_private *mxsfb)
102{
103 u32 reg;
104
105 if (mxsfb->clk_disp_axi)
106 clk_prepare_enable(mxsfb->clk_disp_axi);
107 clk_prepare_enable(mxsfb->clk);
108
109 /* If it was disabled, re-enable the mode again */
110 writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_SET);
111
112 /* Enable the SYNC signals first, then the DMA engine */
113 reg = readl(mxsfb->base + LCDC_VDCTRL4);
114 reg |= VDCTRL4_SYNC_SIGNALS_ON;
115 writel(reg, mxsfb->base + LCDC_VDCTRL4);
116
117 writel(CTRL_RUN, mxsfb->base + LCDC_CTRL + REG_SET);
118}
119
120static void mxsfb_disable_controller(struct mxsfb_drm_private *mxsfb)
121{
122 u32 reg;
123
124 /*
125 * Even if we disable the controller here, it will still continue
126 * until its FIFOs are running out of data
127 */
128 writel(CTRL_DOTCLK_MODE, mxsfb->base + LCDC_CTRL + REG_CLR);
129
130 readl_poll_timeout(mxsfb->base + LCDC_CTRL, reg, !(reg & CTRL_RUN),
131 0, 1000);
132
133 reg = readl(mxsfb->base + LCDC_VDCTRL4);
134 reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
135 writel(reg, mxsfb->base + LCDC_VDCTRL4);
136
137 clk_disable_unprepare(mxsfb->clk);
138 if (mxsfb->clk_disp_axi)
139 clk_disable_unprepare(mxsfb->clk_disp_axi);
140}
141
142/*
143 * Clear the bit and poll it cleared. This is usually called with
144 * a reset address and mask being either SFTRST(bit 31) or CLKGATE
145 * (bit 30).
146 */
147static int clear_poll_bit(void __iomem *addr, u32 mask)
148{
149 u32 reg;
150
151 writel(mask, addr + REG_CLR);
152 return readl_poll_timeout(addr, reg, !(reg & mask), 0, RESET_TIMEOUT);
153}
154
155static int mxsfb_reset_block(struct mxsfb_drm_private *mxsfb)
156{
157 int ret;
158
159 ret = clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_SFTRST);
160 if (ret)
161 return ret;
162
163 writel(CTRL_CLKGATE, mxsfb->base + LCDC_CTRL + REG_CLR);
164
165 ret = clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_SFTRST);
166 if (ret)
167 return ret;
168
169 return clear_poll_bit(mxsfb->base + LCDC_CTRL, CTRL_CLKGATE);
170}
171
172static dma_addr_t mxsfb_get_fb_paddr(struct drm_plane *plane)
173{
174 struct drm_framebuffer *fb = plane->state->fb;
175 struct drm_gem_cma_object *gem;
176
177 if (!fb)
178 return 0;
179
180 gem = drm_fb_cma_get_gem_obj(fb, 0);
181 if (!gem)
182 return 0;
183
184 return gem->paddr;
185}
186
187static void mxsfb_crtc_mode_set_nofb(struct mxsfb_drm_private *mxsfb)
188{
189 struct drm_device *drm = mxsfb->crtc.dev;
190 struct drm_display_mode *m = &mxsfb->crtc.state->adjusted_mode;
191 u32 bus_flags = mxsfb->connector->display_info.bus_flags;
192 u32 vdctrl0, vsync_pulse_len, hsync_pulse_len;
193 int err;
194
195 /*
196 * It seems, you can't re-program the controller if it is still
197 * running. This may lead to shifted pictures (FIFO issue?), so
198 * first stop the controller and drain its FIFOs.
199 */
200
201 /* Mandatory eLCDIF reset as per the Reference Manual */
202 err = mxsfb_reset_block(mxsfb);
203 if (err)
204 return;
205
206 /* Clear the FIFOs */
207 writel(CTRL1_FIFO_CLEAR, mxsfb->base + LCDC_CTRL1 + REG_SET);
208
209 if (mxsfb->devdata->has_overlay)
210 writel(0, mxsfb->base + LCDC_AS_CTRL);
211
212 mxsfb_set_formats(mxsfb);
213
214 clk_set_rate(mxsfb->clk, m->crtc_clock * 1000);
215
216 if (mxsfb->bridge && mxsfb->bridge->timings)
217 bus_flags = mxsfb->bridge->timings->input_bus_flags;
218
219 DRM_DEV_DEBUG_DRIVER(drm->dev, "Pixel clock: %dkHz (actual: %dkHz)\n",
220 m->crtc_clock,
221 (int)(clk_get_rate(mxsfb->clk) / 1000));
222 DRM_DEV_DEBUG_DRIVER(drm->dev, "Connector bus_flags: 0x%08X\n",
223 bus_flags);
224 DRM_DEV_DEBUG_DRIVER(drm->dev, "Mode flags: 0x%08X\n", m->flags);
225
226 writel(TRANSFER_COUNT_SET_VCOUNT(m->crtc_vdisplay) |
227 TRANSFER_COUNT_SET_HCOUNT(m->crtc_hdisplay),
228 mxsfb->base + mxsfb->devdata->transfer_count);
229
230 vsync_pulse_len = m->crtc_vsync_end - m->crtc_vsync_start;
231
232 vdctrl0 = VDCTRL0_ENABLE_PRESENT | /* Always in DOTCLOCK mode */
233 VDCTRL0_VSYNC_PERIOD_UNIT |
234 VDCTRL0_VSYNC_PULSE_WIDTH_UNIT |
235 VDCTRL0_SET_VSYNC_PULSE_WIDTH(vsync_pulse_len);
236 if (m->flags & DRM_MODE_FLAG_PHSYNC)
237 vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH;
238 if (m->flags & DRM_MODE_FLAG_PVSYNC)
239 vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH;
240 /* Make sure Data Enable is high active by default */
241 if (!(bus_flags & DRM_BUS_FLAG_DE_LOW))
242 vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH;
243 /*
244 * DRM_BUS_FLAG_PIXDATA_DRIVE_ defines are controller centric,
245 * controllers VDCTRL0_DOTCLK is display centric.
246 * Drive on positive edge -> display samples on falling edge
247 * DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE -> VDCTRL0_DOTCLK_ACT_FALLING
248 */
249 if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
250 vdctrl0 |= VDCTRL0_DOTCLK_ACT_FALLING;
251
252 writel(vdctrl0, mxsfb->base + LCDC_VDCTRL0);
253
254 /* Frame length in lines. */
255 writel(m->crtc_vtotal, mxsfb->base + LCDC_VDCTRL1);
256
257 /* Line length in units of clocks or pixels. */
258 hsync_pulse_len = m->crtc_hsync_end - m->crtc_hsync_start;
259 writel(set_hsync_pulse_width(mxsfb, hsync_pulse_len) |
260 VDCTRL2_SET_HSYNC_PERIOD(m->crtc_htotal),
261 mxsfb->base + LCDC_VDCTRL2);
262
263 writel(SET_HOR_WAIT_CNT(m->crtc_htotal - m->crtc_hsync_start) |
264 SET_VERT_WAIT_CNT(m->crtc_vtotal - m->crtc_vsync_start),
265 mxsfb->base + LCDC_VDCTRL3);
266
267 writel(SET_DOTCLK_H_VALID_DATA_CNT(m->hdisplay),
268 mxsfb->base + LCDC_VDCTRL4);
269}
270
271static int mxsfb_crtc_atomic_check(struct drm_crtc *crtc,
272 struct drm_crtc_state *state)
273{
274 bool has_primary = state->plane_mask &
275 drm_plane_mask(crtc->primary);
276
277 /* The primary plane has to be enabled when the CRTC is active. */
278 if (state->active && !has_primary)
279 return -EINVAL;
280
281 /* TODO: Is this needed ? */
282 return drm_atomic_add_affected_planes(state->state, crtc);
283}
284
285static void mxsfb_crtc_atomic_flush(struct drm_crtc *crtc,
286 struct drm_crtc_state *old_state)
287{
288 struct drm_pending_vblank_event *event;
289
290 event = crtc->state->event;
291 crtc->state->event = NULL;
292
293 if (!event)
294 return;
295
296 spin_lock_irq(&crtc->dev->event_lock);
297 if (drm_crtc_vblank_get(crtc) == 0)
298 drm_crtc_arm_vblank_event(crtc, event);
299 else
300 drm_crtc_send_vblank_event(crtc, event);
301 spin_unlock_irq(&crtc->dev->event_lock);
302}
303
304static void mxsfb_crtc_atomic_enable(struct drm_crtc *crtc,
305 struct drm_crtc_state *old_state)
306{
307 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev);
308 struct drm_device *drm = mxsfb->drm;
309 dma_addr_t paddr;
310
311 pm_runtime_get_sync(drm->dev);
312 mxsfb_enable_axi_clk(mxsfb);
313
314 drm_crtc_vblank_on(crtc);
315
316 mxsfb_crtc_mode_set_nofb(mxsfb);
317
318 /* Write cur_buf as well to avoid an initial corrupt frame */
319 paddr = mxsfb_get_fb_paddr(crtc->primary);
320 if (paddr) {
321 writel(paddr, mxsfb->base + mxsfb->devdata->cur_buf);
322 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
323 }
324
325 mxsfb_enable_controller(mxsfb);
326}
327
328static void mxsfb_crtc_atomic_disable(struct drm_crtc *crtc,
329 struct drm_crtc_state *old_state)
330{
331 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev);
332 struct drm_device *drm = mxsfb->drm;
333 struct drm_pending_vblank_event *event;
334
335 mxsfb_disable_controller(mxsfb);
336
337 spin_lock_irq(&drm->event_lock);
338 event = crtc->state->event;
339 if (event) {
340 crtc->state->event = NULL;
341 drm_crtc_send_vblank_event(crtc, event);
342 }
343 spin_unlock_irq(&drm->event_lock);
344
345 drm_crtc_vblank_off(crtc);
346
347 mxsfb_disable_axi_clk(mxsfb);
348 pm_runtime_put_sync(drm->dev);
349}
350
351static int mxsfb_crtc_enable_vblank(struct drm_crtc *crtc)
352{
353 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev);
354
355 /* Clear and enable VBLANK IRQ */
356 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
357 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_SET);
358
359 return 0;
360}
361
362static void mxsfb_crtc_disable_vblank(struct drm_crtc *crtc)
363{
364 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(crtc->dev);
365
366 /* Disable and clear VBLANK IRQ */
367 writel(CTRL1_CUR_FRAME_DONE_IRQ_EN, mxsfb->base + LCDC_CTRL1 + REG_CLR);
368 writel(CTRL1_CUR_FRAME_DONE_IRQ, mxsfb->base + LCDC_CTRL1 + REG_CLR);
369}
370
371static const struct drm_crtc_helper_funcs mxsfb_crtc_helper_funcs = {
372 .atomic_check = mxsfb_crtc_atomic_check,
373 .atomic_flush = mxsfb_crtc_atomic_flush,
374 .atomic_enable = mxsfb_crtc_atomic_enable,
375 .atomic_disable = mxsfb_crtc_atomic_disable,
376};
377
378static const struct drm_crtc_funcs mxsfb_crtc_funcs = {
379 .reset = drm_atomic_helper_crtc_reset,
380 .destroy = drm_crtc_cleanup,
381 .set_config = drm_atomic_helper_set_config,
382 .page_flip = drm_atomic_helper_page_flip,
383 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
384 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
385 .enable_vblank = mxsfb_crtc_enable_vblank,
386 .disable_vblank = mxsfb_crtc_disable_vblank,
387};
388
389/* -----------------------------------------------------------------------------
390 * Encoder
391 */
392
393static const struct drm_encoder_funcs mxsfb_encoder_funcs = {
394 .destroy = drm_encoder_cleanup,
395};
396
397/* -----------------------------------------------------------------------------
398 * Planes
399 */
400
401static int mxsfb_plane_atomic_check(struct drm_plane *plane,
402 struct drm_plane_state *plane_state)
403{
404 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev);
405 struct drm_crtc_state *crtc_state;
406
407 crtc_state = drm_atomic_get_new_crtc_state(plane_state->state,
408 &mxsfb->crtc);
409
410 return drm_atomic_helper_check_plane_state(plane_state, crtc_state,
411 DRM_PLANE_HELPER_NO_SCALING,
412 DRM_PLANE_HELPER_NO_SCALING,
413 false, true);
414}
415
416static void mxsfb_plane_primary_atomic_update(struct drm_plane *plane,
417 struct drm_plane_state *old_pstate)
418{
419 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev);
420 dma_addr_t paddr;
421
422 paddr = mxsfb_get_fb_paddr(plane);
423 if (paddr)
424 writel(paddr, mxsfb->base + mxsfb->devdata->next_buf);
425}
426
427static void mxsfb_plane_overlay_atomic_update(struct drm_plane *plane,
428 struct drm_plane_state *old_pstate)
429{
430 struct mxsfb_drm_private *mxsfb = to_mxsfb_drm_private(plane->dev);
431 struct drm_plane_state *state = plane->state;
432 dma_addr_t paddr;
433 u32 ctrl;
434
435 paddr = mxsfb_get_fb_paddr(plane);
436 if (!paddr) {
437 writel(0, mxsfb->base + LCDC_AS_CTRL);
438 return;
439 }
440
441 /*
442 * HACK: The hardware seems to output 64 bytes of data of unknown
443 * origin, and then to proceed with the framebuffer. Until the reason
444 * is understood, live with the 16 initial invalid pixels on the first
445 * line and start 64 bytes within the framebuffer.
446 */
447 paddr += 64;
448
449 writel(paddr, mxsfb->base + LCDC_AS_NEXT_BUF);
450
451 /*
452 * If the plane was previously disabled, write LCDC_AS_BUF as well to
453 * provide the first buffer.
454 */
455 if (!old_pstate->fb)
456 writel(paddr, mxsfb->base + LCDC_AS_BUF);
457
458 ctrl = AS_CTRL_AS_ENABLE | AS_CTRL_ALPHA(255);
459
460 switch (state->fb->format->format) {
461 case DRM_FORMAT_XRGB4444:
462 ctrl |= AS_CTRL_FORMAT_RGB444 | AS_CTRL_ALPHA_CTRL_OVERRIDE;
463 break;
464 case DRM_FORMAT_ARGB4444:
465 ctrl |= AS_CTRL_FORMAT_ARGB4444 | AS_CTRL_ALPHA_CTRL_EMBEDDED;
466 break;
467 case DRM_FORMAT_XRGB1555:
468 ctrl |= AS_CTRL_FORMAT_RGB555 | AS_CTRL_ALPHA_CTRL_OVERRIDE;
469 break;
470 case DRM_FORMAT_ARGB1555:
471 ctrl |= AS_CTRL_FORMAT_ARGB1555 | AS_CTRL_ALPHA_CTRL_EMBEDDED;
472 break;
473 case DRM_FORMAT_RGB565:
474 ctrl |= AS_CTRL_FORMAT_RGB565 | AS_CTRL_ALPHA_CTRL_OVERRIDE;
475 break;
476 case DRM_FORMAT_XRGB8888:
477 ctrl |= AS_CTRL_FORMAT_RGB888 | AS_CTRL_ALPHA_CTRL_OVERRIDE;
478 break;
479 case DRM_FORMAT_ARGB8888:
480 ctrl |= AS_CTRL_FORMAT_ARGB8888 | AS_CTRL_ALPHA_CTRL_EMBEDDED;
481 break;
482 }
483
484 writel(ctrl, mxsfb->base + LCDC_AS_CTRL);
485}
486
487static const struct drm_plane_helper_funcs mxsfb_plane_primary_helper_funcs = {
488 .atomic_check = mxsfb_plane_atomic_check,
489 .atomic_update = mxsfb_plane_primary_atomic_update,
490};
491
492static const struct drm_plane_helper_funcs mxsfb_plane_overlay_helper_funcs = {
493 .atomic_check = mxsfb_plane_atomic_check,
494 .atomic_update = mxsfb_plane_overlay_atomic_update,
495};
496
497static const struct drm_plane_funcs mxsfb_plane_funcs = {
498 .update_plane = drm_atomic_helper_update_plane,
499 .disable_plane = drm_atomic_helper_disable_plane,
500 .destroy = drm_plane_cleanup,
501 .reset = drm_atomic_helper_plane_reset,
502 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
503 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
504};
505
506static const uint32_t mxsfb_primary_plane_formats[] = {
507 DRM_FORMAT_RGB565,
508 DRM_FORMAT_XRGB8888,
509};
510
511static const uint32_t mxsfb_overlay_plane_formats[] = {
512 DRM_FORMAT_XRGB4444,
513 DRM_FORMAT_ARGB4444,
514 DRM_FORMAT_XRGB1555,
515 DRM_FORMAT_ARGB1555,
516 DRM_FORMAT_RGB565,
517 DRM_FORMAT_XRGB8888,
518 DRM_FORMAT_ARGB8888,
519};
520
521static const uint64_t mxsfb_modifiers[] = {
522 DRM_FORMAT_MOD_LINEAR,
523 DRM_FORMAT_MOD_INVALID
524};
525
526/* -----------------------------------------------------------------------------
527 * Initialization
528 */
529
530int mxsfb_kms_init(struct mxsfb_drm_private *mxsfb)
531{
532 struct drm_encoder *encoder = &mxsfb->encoder;
533 struct drm_crtc *crtc = &mxsfb->crtc;
534 int ret;
535
536 drm_plane_helper_add(&mxsfb->planes.primary,
537 &mxsfb_plane_primary_helper_funcs);
538 ret = drm_universal_plane_init(mxsfb->drm, &mxsfb->planes.primary, 1,
539 &mxsfb_plane_funcs,
540 mxsfb_primary_plane_formats,
541 ARRAY_SIZE(mxsfb_primary_plane_formats),
542 mxsfb_modifiers, DRM_PLANE_TYPE_PRIMARY,
543 NULL);
544 if (ret)
545 return ret;
546
547 if (mxsfb->devdata->has_overlay) {
548 drm_plane_helper_add(&mxsfb->planes.overlay,
549 &mxsfb_plane_overlay_helper_funcs);
550 ret = drm_universal_plane_init(mxsfb->drm,
551 &mxsfb->planes.overlay, 1,
552 &mxsfb_plane_funcs,
553 mxsfb_overlay_plane_formats,
554 ARRAY_SIZE(mxsfb_overlay_plane_formats),
555 mxsfb_modifiers, DRM_PLANE_TYPE_OVERLAY,
556 NULL);
557 if (ret)
558 return ret;
559 }
560
561 drm_crtc_helper_add(crtc, &mxsfb_crtc_helper_funcs);
562 ret = drm_crtc_init_with_planes(mxsfb->drm, crtc,
563 &mxsfb->planes.primary, NULL,
564 &mxsfb_crtc_funcs, NULL);
565 if (ret)
566 return ret;
567
568 encoder->possible_crtcs = drm_crtc_mask(crtc);
569 return drm_encoder_init(mxsfb->drm, encoder, &mxsfb_encoder_funcs,
570 DRM_MODE_ENCODER_NONE, NULL);
571}
drivers/gpu/drm/mxsfb/mxsfb_out.c+0−99
@@ -1,99 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2016 Marek Vasut <marex@denx.de>
4 */
5
6#include <linux/of_graph.h>
7
8#include <drm/drm_atomic.h>
9#include <drm/drm_atomic_helper.h>
10#include <drm/drm_crtc.h>
11#include <drm/drm_fb_cma_helper.h>
12#include <drm/drm_gem_cma_helper.h>
13#include <drm/drm_of.h>
14#include <drm/drm_panel.h>
15#include <drm/drm_plane_helper.h>
16#include <drm/drm_probe_helper.h>
17#include <drm/drm_simple_kms_helper.h>
18
19#include "mxsfb_drv.h"
20
21static struct mxsfb_drm_private *
22drm_connector_to_mxsfb_drm_private(struct drm_connector *connector)
23{
24 return container_of(connector, struct mxsfb_drm_private,
25 panel_connector);
26}
27
28static int mxsfb_panel_get_modes(struct drm_connector *connector)
29{
30 struct mxsfb_drm_private *mxsfb =
31 drm_connector_to_mxsfb_drm_private(connector);
32
33 if (mxsfb->panel)
34 return drm_panel_get_modes(mxsfb->panel, connector);
35
36 return 0;
37}
38
39static const struct
40drm_connector_helper_funcs mxsfb_panel_connector_helper_funcs = {
41 .get_modes = mxsfb_panel_get_modes,
42};
43
44static enum drm_connector_status
45mxsfb_panel_connector_detect(struct drm_connector *connector, bool force)
46{
47 struct mxsfb_drm_private *mxsfb =
48 drm_connector_to_mxsfb_drm_private(connector);
49
50 if (mxsfb->panel)
51 return connector_status_connected;
52
53 return connector_status_disconnected;
54}
55
56static void mxsfb_panel_connector_destroy(struct drm_connector *connector)
57{
58 struct mxsfb_drm_private *mxsfb =
59 drm_connector_to_mxsfb_drm_private(connector);
60
61 if (mxsfb->panel)
62 drm_panel_detach(mxsfb->panel);
63
64 drm_connector_unregister(connector);
65 drm_connector_cleanup(connector);
66}
67
68static const struct drm_connector_funcs mxsfb_panel_connector_funcs = {
69 .detect = mxsfb_panel_connector_detect,
70 .fill_modes = drm_helper_probe_single_connector_modes,
71 .destroy = mxsfb_panel_connector_destroy,
72 .reset = drm_atomic_helper_connector_reset,
73 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
74 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
75};
76
77int mxsfb_create_output(struct drm_device *drm)
78{
79 struct mxsfb_drm_private *mxsfb = drm->dev_private;
80 int ret;
81
82 ret = drm_of_find_panel_or_bridge(drm->dev->of_node, 0, 0,
83 &mxsfb->panel, &mxsfb->bridge);
84 if (ret)
85 return ret;
86
87 if (mxsfb->panel) {
88 mxsfb->connector = &mxsfb->panel_connector;
89 mxsfb->connector->dpms = DRM_MODE_DPMS_OFF;
90 mxsfb->connector->polled = 0;
91 drm_connector_helper_add(mxsfb->connector,
92 &mxsfb_panel_connector_helper_funcs);
93 ret = drm_connector_init(drm, mxsfb->connector,
94 &mxsfb_panel_connector_funcs,
95 DRM_MODE_CONNECTOR_Unknown);
96 }
97
98 return ret;
99}
drivers/gpu/drm/mxsfb/mxsfb_regs.h+60−47
@@ -27,52 +27,61 @@ · 26 unmodified lines
27#define LCDC_VDCTRL4 0xb027#define LCDC_VDCTRL4 0xb0
28#define LCDC_V4_DEBUG0 0x1d028#define LCDC_V4_DEBUG0 0x1d0
29#define LCDC_V3_DEBUG0 0x1f029#define LCDC_V3_DEBUG0 0x1f0
30 30#define LCDC_AS_CTRL 0x210
31#define CTRL_SFTRST (1 << 31)31#define LCDC_AS_BUF 0x220
32#define CTRL_CLKGATE (1 << 30)32#define LCDC_AS_NEXT_BUF 0x230
33#define CTRL_BYPASS_COUNT (1 << 19)33#define LCDC_AS_CLRKEYLOW 0x240
34#define CTRL_VSYNC_MODE (1 << 18)34#define LCDC_AS_CLRKEYHIGH 0x250
35#define CTRL_DOTCLK_MODE (1 << 17)35
36#define CTRL_DATA_SELECT (1 << 16)36#define CTRL_SFTRST BIT(31)
37#define CTRL_SET_BUS_WIDTH(x) (((x) & 0x3) << 10)37#define CTRL_CLKGATE BIT(30)
38#define CTRL_GET_BUS_WIDTH(x) (((x) >> 10) & 0x3)38#define CTRL_BYPASS_COUNT BIT(19)
39#define CTRL_VSYNC_MODE BIT(18)
40#define CTRL_DOTCLK_MODE BIT(17)
41#define CTRL_DATA_SELECT BIT(16)
42#define CTRL_BUS_WIDTH_16 (0 << 10)
43#define CTRL_BUS_WIDTH_8 (1 << 10)
44#define CTRL_BUS_WIDTH_18 (2 << 10)
45#define CTRL_BUS_WIDTH_24 (3 << 10)
39#define CTRL_BUS_WIDTH_MASK (0x3 << 10)46#define CTRL_BUS_WIDTH_MASK (0x3 << 10)
40#define CTRL_SET_WORD_LENGTH(x) (((x) & 0x3) << 8)47#define CTRL_WORD_LENGTH_16 (0 << 8)
41#define CTRL_GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)48#define CTRL_WORD_LENGTH_8 (1 << 8)
42#define CTRL_MASTER (1 << 5)49#define CTRL_WORD_LENGTH_18 (2 << 8)
43#define CTRL_DF16 (1 << 3)50#define CTRL_WORD_LENGTH_24 (3 << 8)
44#define CTRL_DF18 (1 << 2)51#define CTRL_MASTER BIT(5)
45#define CTRL_DF24 (1 << 1)52#define CTRL_DF16 BIT(3)
46#define CTRL_RUN (1 << 0)53#define CTRL_DF18 BIT(2)
47 54#define CTRL_DF24 BIT(1)
48#define CTRL1_FIFO_CLEAR (1 << 21)55#define CTRL_RUN BIT(0)
56
57#define CTRL1_FIFO_CLEAR BIT(21)
49#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)58#define CTRL1_SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
50#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)59#define CTRL1_GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
51#define CTRL1_CUR_FRAME_DONE_IRQ_EN (1 << 13)60#define CTRL1_CUR_FRAME_DONE_IRQ_EN BIT(13)
52#define CTRL1_CUR_FRAME_DONE_IRQ (1 << 9)61#define CTRL1_CUR_FRAME_DONE_IRQ BIT(9)
53 62
54#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)63#define TRANSFER_COUNT_SET_VCOUNT(x) (((x) & 0xffff) << 16)
55#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)64#define TRANSFER_COUNT_GET_VCOUNT(x) (((x) >> 16) & 0xffff)
56#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)65#define TRANSFER_COUNT_SET_HCOUNT(x) ((x) & 0xffff)
57#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)66#define TRANSFER_COUNT_GET_HCOUNT(x) ((x) & 0xffff)
58 67
59#define VDCTRL0_ENABLE_PRESENT (1 << 28)68#define VDCTRL0_ENABLE_PRESENT BIT(28)
60#define VDCTRL0_VSYNC_ACT_HIGH (1 << 27)69#define VDCTRL0_VSYNC_ACT_HIGH BIT(27)
61#define VDCTRL0_HSYNC_ACT_HIGH (1 << 26)70#define VDCTRL0_HSYNC_ACT_HIGH BIT(26)
62#define VDCTRL0_DOTCLK_ACT_FALLING (1 << 25)71#define VDCTRL0_DOTCLK_ACT_FALLING BIT(25)
63#define VDCTRL0_ENABLE_ACT_HIGH (1 << 24)72#define VDCTRL0_ENABLE_ACT_HIGH BIT(24)
64#define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)73#define VDCTRL0_VSYNC_PERIOD_UNIT BIT(21)
65#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)74#define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT BIT(20)
66#define VDCTRL0_HALF_LINE (1 << 19)75#define VDCTRL0_HALF_LINE BIT(19)
67#define VDCTRL0_HALF_LINE_MODE (1 << 18)76#define VDCTRL0_HALF_LINE_MODE BIT(18)
68#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)77#define VDCTRL0_SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
69#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)78#define VDCTRL0_GET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
70 79
71#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)80#define VDCTRL2_SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
72#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)81#define VDCTRL2_GET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
73 82
74#define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)83#define VDCTRL3_MUX_SYNC_SIGNALS BIT(29)
75#define VDCTRL3_VSYNC_ONLY (1 << 28)84#define VDCTRL3_VSYNC_ONLY BIT(28)
76#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)85#define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
77#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)86#define GET_HOR_WAIT_CNT(x) (((x) >> 16) & 0xfff)
78#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)87#define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
@@ -80,28 +89,32 @@ · 1 unmodified line
80 89
81#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */90#define VDCTRL4_SET_DOTCLK_DLY(x) (((x) & 0x7) << 29) /* v4 only */
82#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */91#define VDCTRL4_GET_DOTCLK_DLY(x) (((x) >> 29) & 0x7) /* v4 only */
83#define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)92#define VDCTRL4_SYNC_SIGNALS_ON BIT(18)
84#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)93#define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
85 94
86#define DEBUG0_HSYNC (1 < 26)95#define DEBUG0_HSYNC BIT(26)
87#define DEBUG0_VSYNC (1 < 25)96#define DEBUG0_VSYNC BIT(25)
97
98#define AS_CTRL_PS_DISABLE BIT(23)
99#define AS_CTRL_ALPHA_INVERT BIT(20)
100#define AS_CTRL_ALPHA(a) (((a) & 0xff) << 8)
101#define AS_CTRL_FORMAT_RGB565 (0xe << 4)
102#define AS_CTRL_FORMAT_RGB444 (0xd << 4)
103#define AS_CTRL_FORMAT_RGB555 (0xc << 4)
104#define AS_CTRL_FORMAT_ARGB4444 (0x9 << 4)
105#define AS_CTRL_FORMAT_ARGB1555 (0x8 << 4)
106#define AS_CTRL_FORMAT_RGB888 (0x4 << 4)
107#define AS_CTRL_FORMAT_ARGB8888 (0x0 << 4)
108#define AS_CTRL_ENABLE_COLORKEY BIT(3)
109#define AS_CTRL_ALPHA_CTRL_ROP (3 << 1)
110#define AS_CTRL_ALPHA_CTRL_MULTIPLY (2 << 1)
111#define AS_CTRL_ALPHA_CTRL_OVERRIDE (1 << 1)
112#define AS_CTRL_ALPHA_CTRL_EMBEDDED (0 << 1)
113#define AS_CTRL_AS_ENABLE BIT(0)
88 114
89#define MXSFB_MIN_XRES 120115#define MXSFB_MIN_XRES 120
90#define MXSFB_MIN_YRES 120116#define MXSFB_MIN_YRES 120
91#define MXSFB_MAX_XRES 0xffff117#define MXSFB_MAX_XRES 0xffff
92#define MXSFB_MAX_YRES 0xffff118#define MXSFB_MAX_YRES 0xffff
93 119
94#define RED 0
95#define GREEN 1
96#define BLUE 2
97#define TRANSP 3
98
99#define STMLCDIF_8BIT 1 /* pixel data bus to the display is of 8 bit width */
100#define STMLCDIF_16BIT 0 /* pixel data bus to the display is of 16 bit width */
101#define STMLCDIF_18BIT 2 /* pixel data bus to the display is of 18 bit width */
102#define STMLCDIF_24BIT 3 /* pixel data bus to the display is of 24 bit width */
103
104#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
105#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negative edge sampling */
106
107#endif /* __MXSFB_REGS_H__ */120#endif /* __MXSFB_REGS_H__ */
drivers/gpu/drm/nouveau/nouveau_bo.c+18−119
@@ -646,66 +646,6 @@ nouveau_ttm_tt_create(struct ttm_buffer_object *bo, uint32_t page_flags) · 645 unmodified lines
646 return nouveau_sgdma_create_ttm(bo, page_flags);646 return nouveau_sgdma_create_ttm(bo, page_flags);
647}647}
648 648
649static int
650nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
651 struct ttm_mem_type_manager *man)
652{
653 struct nouveau_drm *drm = nouveau_bdev(bdev);
654 struct nvif_mmu *mmu = &drm->client.mmu;
655
656 switch (type) {
657 case TTM_PL_SYSTEM:
658 man->flags = 0;
659 man->available_caching = TTM_PL_MASK_CACHING;
660 man->default_caching = TTM_PL_FLAG_CACHED;
661 break;
662 case TTM_PL_VRAM:
663 man->flags = TTM_MEMTYPE_FLAG_FIXED;
664 man->available_caching = TTM_PL_FLAG_UNCACHED |
665 TTM_PL_FLAG_WC;
666 man->default_caching = TTM_PL_FLAG_WC;
667
668 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
669 /* Some BARs do not support being ioremapped WC */
670 const u8 type = mmu->type[drm->ttm.type_vram].type;
671 if (type & NVIF_MEM_UNCACHED) {
672 man->available_caching = TTM_PL_FLAG_UNCACHED;
673 man->default_caching = TTM_PL_FLAG_UNCACHED;
674 }
675
676 man->func = &nouveau_vram_manager;
677 man->use_io_reserve_lru = true;
678 } else {
679 man->func = &ttm_bo_manager_func;
680 }
681 break;
682 case TTM_PL_TT:
683 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA)
684 man->func = &nouveau_gart_manager;
685 else
686 if (!drm->agp.bridge)
687 man->func = &nv04_gart_manager;
688 else
689 man->func = &ttm_bo_manager_func;
690
691 if (drm->agp.bridge) {
692 man->flags = 0;
693 man->available_caching = TTM_PL_FLAG_UNCACHED |
694 TTM_PL_FLAG_WC;
695 man->default_caching = TTM_PL_FLAG_WC;
696 } else {
697 man->flags = 0;
698 man->available_caching = TTM_PL_MASK_CACHING;
699 man->default_caching = TTM_PL_FLAG_CACHED;
700 }
701
702 break;
703 default:
704 return -EINVAL;
705 }
706 return 0;
707}
708
709static void649static void
710nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)650nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
711{651{
@@ -726,7 +666,7 @@ nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl) · 14 unmodified lines
726 666
727static int667static int
728nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo,668nouveau_bo_move_prep(struct nouveau_drm *drm, struct ttm_buffer_object *bo,
729 struct ttm_mem_reg *reg)669 struct ttm_resource *reg)
730{670{
731 struct nouveau_mem *old_mem = nouveau_mem(&bo->mem);671 struct nouveau_mem *old_mem = nouveau_mem(&bo->mem);
732 struct nouveau_mem *new_mem = nouveau_mem(reg);672 struct nouveau_mem *new_mem = nouveau_mem(reg);
@@ -758,7 +698,7 @@ done: · 25 unmodified lines
758 698
759static int699static int
760nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,700nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
761 bool no_wait_gpu, struct ttm_mem_reg *new_reg)701 bool no_wait_gpu, struct ttm_resource *new_reg)
762{702{
763 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);703 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
764 struct nouveau_channel *chan = drm->ttm.chan;704 struct nouveau_channel *chan = drm->ttm.chan;
@@ -768,7 +708,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, · 3 unmodified lines
768 708
769 /* create temporary vmas for the transfer and attach them to the709 /* create temporary vmas for the transfer and attach them to the
770 * old nvkm_mem node, these will get cleaned up after ttm has710 * old nvkm_mem node, these will get cleaned up after ttm has
771 * destroyed the ttm_mem_reg711 * destroyed the ttm_resource
772 */712 */
773 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {713 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
774 ret = nouveau_bo_move_prep(drm, bo, new_reg);714 ret = nouveau_bo_move_prep(drm, bo, new_reg);
@@ -804,7 +744,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) · 29 unmodified lines
804 s32 oclass;744 s32 oclass;
805 int (*exec)(struct nouveau_channel *,745 int (*exec)(struct nouveau_channel *,
806 struct ttm_buffer_object *,746 struct ttm_buffer_object *,
807 struct ttm_mem_reg *, struct ttm_mem_reg *);747 struct ttm_resource *, struct ttm_resource *);
808 int (*init)(struct nouveau_channel *, u32 handle);748 int (*init)(struct nouveau_channel *, u32 handle);
809 } _methods[] = {749 } _methods[] = {
810 { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },750 { "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
@@ -865,7 +805,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) · 54 unmodified lines
865 805
866static int806static int
867nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,807nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
868 bool no_wait_gpu, struct ttm_mem_reg *new_reg)808 bool no_wait_gpu, struct ttm_resource *new_reg)
869{809{
870 struct ttm_operation_ctx ctx = { intr, no_wait_gpu };810 struct ttm_operation_ctx ctx = { intr, no_wait_gpu };
871 struct ttm_place placement_memtype = {811 struct ttm_place placement_memtype = {
@@ -874,7 +814,7 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, · 2 unmodified lines
874 .flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING814 .flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING
875 };815 };
876 struct ttm_placement placement;816 struct ttm_placement placement;
877 struct ttm_mem_reg tmp_reg;817 struct ttm_resource tmp_reg;
878 int ret;818 int ret;
879 819
880 placement.num_placement = placement.num_busy_placement = 1;820 placement.num_placement = placement.num_busy_placement = 1;
@@ -896,13 +836,13 @@ nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr, · 15 unmodified lines
896 836
897 ret = ttm_bo_move_ttm(bo, &ctx, new_reg);837 ret = ttm_bo_move_ttm(bo, &ctx, new_reg);
898out:838out:
899 ttm_bo_mem_put(bo, &tmp_reg);839 ttm_resource_free(bo, &tmp_reg);
900 return ret;840 return ret;
901}841}
902 842
903static int843static int
904nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,844nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
905 bool no_wait_gpu, struct ttm_mem_reg *new_reg)845 bool no_wait_gpu, struct ttm_resource *new_reg)
906{846{
907 struct ttm_operation_ctx ctx = { intr, no_wait_gpu };847 struct ttm_operation_ctx ctx = { intr, no_wait_gpu };
908 struct ttm_place placement_memtype = {848 struct ttm_place placement_memtype = {
@@ -911,7 +851,7 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, · 2 unmodified lines
911 .flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING851 .flags = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING
912 };852 };
913 struct ttm_placement placement;853 struct ttm_placement placement;
914 struct ttm_mem_reg tmp_reg;854 struct ttm_resource tmp_reg;
915 int ret;855 int ret;
916 856
917 placement.num_placement = placement.num_busy_placement = 1;857 placement.num_placement = placement.num_busy_placement = 1;
@@ -932,13 +872,13 @@ nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr, · 14 unmodified lines
932 goto out;872 goto out;
933 873
934out:874out:
935 ttm_bo_mem_put(bo, &tmp_reg);875 ttm_resource_free(bo, &tmp_reg);
936 return ret;876 return ret;
937}877}
938 878
939static void879static void
940nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict,880nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict,
941 struct ttm_mem_reg *new_reg)881 struct ttm_resource *new_reg)
942{882{
943 struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL;883 struct nouveau_mem *mem = new_reg ? nouveau_mem(new_reg) : NULL;
944 struct nouveau_bo *nvbo = nouveau_bo(bo);884 struct nouveau_bo *nvbo = nouveau_bo(bo);
@@ -970,7 +910,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, bool evict, · 25 unmodified lines
970}910}
971 911
972static int912static int
973nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_reg,913nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_resource *new_reg,
974 struct nouveau_drm_tile **new_tile)914 struct nouveau_drm_tile **new_tile)
975{915{
976 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);916 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
@@ -1006,11 +946,11 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, · 29 unmodified lines
1006static int946static int
1007nouveau_bo_move(struct ttm_buffer_object *bo, bool evict,947nouveau_bo_move(struct ttm_buffer_object *bo, bool evict,
1008 struct ttm_operation_ctx *ctx,948 struct ttm_operation_ctx *ctx,
1009 struct ttm_mem_reg *new_reg)949 struct ttm_resource *new_reg)
1010{950{
1011 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);951 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
1012 struct nouveau_bo *nvbo = nouveau_bo(bo);952 struct nouveau_bo *nvbo = nouveau_bo(bo);
1013 struct ttm_mem_reg *old_reg = &bo->mem;953 struct ttm_resource *old_reg = &bo->mem;
1014 struct nouveau_drm_tile *new_tile = NULL;954 struct nouveau_drm_tile *new_tile = NULL;
1015 int ret = 0;955 int ret = 0;
1016 956
@@ -1079,18 +1019,12 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) · 62 unmodified lines
1079}1019}
1080 1020
1081static int1021static int
1082nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg)1022nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_resource *reg)
1083{1023{
1084 struct nouveau_drm *drm = nouveau_bdev(bdev);1024 struct nouveau_drm *drm = nouveau_bdev(bdev);
1085 struct nvkm_device *device = nvxx_device(&drm->client.device);1025 struct nvkm_device *device = nvxx_device(&drm->client.device);
1086 struct nouveau_mem *mem = nouveau_mem(reg);1026 struct nouveau_mem *mem = nouveau_mem(reg);
1087 1027
1088 reg->bus.addr = NULL;
1089 reg->bus.offset = 0;
1090 reg->bus.size = reg->num_pages << PAGE_SHIFT;
1091 reg->bus.base = 0;
1092 reg->bus.is_iomem = false;
1093
1094 switch (reg->mem_type) {1028 switch (reg->mem_type) {
1095 case TTM_PL_SYSTEM:1029 case TTM_PL_SYSTEM:
1096 /* System memory */1030 /* System memory */
@@ -1159,7 +1093,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) · 62 unmodified lines
1159}1093}
1160 1094
1161static void1095static void
1162nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg)1096nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_resource *reg)
1163{1097{
1164 struct nouveau_drm *drm = nouveau_bdev(bdev);1098 struct nouveau_drm *drm = nouveau_bdev(bdev);
1165 struct nouveau_mem *mem = nouveau_mem(reg);1099 struct nouveau_mem *mem = nouveau_mem(reg);
@@ -1231,8 +1165,6 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) · 65 unmodified lines
1231 struct ttm_dma_tt *ttm_dma = (void *)ttm;1165 struct ttm_dma_tt *ttm_dma = (void *)ttm;
1232 struct nouveau_drm *drm;1166 struct nouveau_drm *drm;
1233 struct device *dev;1167 struct device *dev;
1234 unsigned i;
1235 int r;
1236 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);1168 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
1237 1169
1238 if (ttm->state != tt_unpopulated)1170 if (ttm->state != tt_unpopulated)
@@ -1260,31 +1192,7 @@ nouveau_ttm_tt_populate(struct ttm_tt *ttm, struct ttm_operation_ctx *ctx) · 21 unmodified lines
1260 return ttm_dma_populate((void *)ttm, dev, ctx);1192 return ttm_dma_populate((void *)ttm, dev, ctx);
1261 }1193 }
1262#endif1194#endif
1263 1195 return ttm_populate_and_map_pages(dev, ttm_dma, ctx);
1264 r = ttm_pool_populate(ttm, ctx);
1265 if (r) {
1266 return r;
1267 }
1268
1269 for (i = 0; i < ttm->num_pages; i++) {
1270 dma_addr_t addr;
1271
1272 addr = dma_map_page(dev, ttm->pages[i], 0, PAGE_SIZE,
1273 DMA_BIDIRECTIONAL);
1274
1275 if (dma_mapping_error(dev, addr)) {
1276 while (i--) {
1277 dma_unmap_page(dev, ttm_dma->dma_address[i],
1278 PAGE_SIZE, DMA_BIDIRECTIONAL);
1279 ttm_dma->dma_address[i] = 0;
1280 }
1281 ttm_pool_unpopulate(ttm);
1282 return -EFAULT;
1283 }
1284
1285 ttm_dma->dma_address[i] = addr;
1286 }
1287 return 0;
1288}1196}
1289 1197
1290static void1198static void
@@ -1293,7 +1201,6 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) · 2 unmodified lines
1293 struct ttm_dma_tt *ttm_dma = (void *)ttm;1201 struct ttm_dma_tt *ttm_dma = (void *)ttm;
1294 struct nouveau_drm *drm;1202 struct nouveau_drm *drm;
1295 struct device *dev;1203 struct device *dev;
1296 unsigned i;
1297 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);1204 bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
1298 1205
1299 if (slave)1206 if (slave)
@@ -1316,14 +1223,7 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) · 16 unmodified lines
1316 }1223 }
1317#endif1224#endif
1318 1225
1319 for (i = 0; i < ttm->num_pages; i++) {1226 ttm_unmap_and_unpopulate_pages(dev, ttm_dma);
1320 if (ttm_dma->dma_address[i]) {
1321 dma_unmap_page(dev, ttm_dma->dma_address[i], PAGE_SIZE,
1322 DMA_BIDIRECTIONAL);
1323 }
1324 }
1325
1326 ttm_pool_unpopulate(ttm);
1327}1227}
1328 1228
1329void1229void
@@ -1341,7 +1241,6 @@ struct ttm_bo_driver nouveau_bo_driver = { · 11 unmodified lines
1341 .ttm_tt_create = &nouveau_ttm_tt_create,1241 .ttm_tt_create = &nouveau_ttm_tt_create,
1342 .ttm_tt_populate = &nouveau_ttm_tt_populate,1242 .ttm_tt_populate = &nouveau_ttm_tt_populate,
1343 .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate,1243 .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate,
1344 .init_mem_type = nouveau_bo_init_mem_type,
1345 .eviction_valuable = ttm_bo_eviction_valuable,1244 .eviction_valuable = ttm_bo_eviction_valuable,
1346 .evict_flags = nouveau_bo_evict_flags,1245 .evict_flags = nouveau_bo_evict_flags,
1347 .move_notify = nouveau_bo_move_ntfy,1246 .move_notify = nouveau_bo_move_ntfy,
drivers/gpu/drm/nouveau/nouveau_bo.h+7−7
@@ -139,28 +139,28 @@ nouveau_bo_new_pin_map(struct nouveau_cli *cli, u64 size, int align, u32 flags, · 138 unmodified lines
139 139
140int nv04_bo_move_init(struct nouveau_channel *, u32);140int nv04_bo_move_init(struct nouveau_channel *, u32);
141int nv04_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,141int nv04_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,
142 struct ttm_mem_reg *, struct ttm_mem_reg *);142 struct ttm_resource *, struct ttm_resource *);
143 143
144int nv50_bo_move_init(struct nouveau_channel *, u32);144int nv50_bo_move_init(struct nouveau_channel *, u32);
145int nv50_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,145int nv50_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,
146 struct ttm_mem_reg *, struct ttm_mem_reg *);146 struct ttm_resource *, struct ttm_resource *);
147 147
148int nv84_bo_move_exec(struct nouveau_channel *, struct ttm_buffer_object *,148int nv84_bo_move_exec(struct nouveau_channel *, struct ttm_buffer_object *,
149 struct ttm_mem_reg *, struct ttm_mem_reg *);149 struct ttm_resource *, struct ttm_resource *);
150 150
151int nva3_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,151int nva3_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,
152 struct ttm_mem_reg *, struct ttm_mem_reg *);152 struct ttm_resource *, struct ttm_resource *);
153 153
154int nvc0_bo_move_init(struct nouveau_channel *, u32);154int nvc0_bo_move_init(struct nouveau_channel *, u32);
155int nvc0_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,155int nvc0_bo_move_m2mf(struct nouveau_channel *, struct ttm_buffer_object *,
156 struct ttm_mem_reg *, struct ttm_mem_reg *);156 struct ttm_resource *, struct ttm_resource *);
157 157
158int nvc0_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,158int nvc0_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,
159 struct ttm_mem_reg *, struct ttm_mem_reg *);159 struct ttm_resource *, struct ttm_resource *);
160 160
161int nve0_bo_move_init(struct nouveau_channel *, u32);161int nve0_bo_move_init(struct nouveau_channel *, u32);
162int nve0_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,162int nve0_bo_move_copy(struct nouveau_channel *, struct ttm_buffer_object *,
163 struct ttm_mem_reg *, struct ttm_mem_reg *);163 struct ttm_resource *, struct ttm_resource *);
164 164
165#define NVBO_WR32_(b,o,dr,f) nouveau_bo_wr32((b), (o)/4 + (dr), (f))165#define NVBO_WR32_(b,o,dr,f) nouveau_bo_wr32((b), (o)/4 + (dr), (f))
166#define NVBO_RD32_(b,o,dr) nouveau_bo_rd32((b), (o)/4 + (dr))166#define NVBO_RD32_(b,o,dr) nouveau_bo_rd32((b), (o)/4 + (dr))
drivers/gpu/drm/nouveau/nouveau_bo0039.c+2−2
@@ -36,7 +36,7 @@ · 35 unmodified lines
36 36
37static inline uint32_t37static inline uint32_t
38nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,38nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
39 struct nouveau_channel *chan, struct ttm_mem_reg *reg)39 struct nouveau_channel *chan, struct ttm_resource *reg)
40{40{
41 if (reg->mem_type == TTM_PL_TT)41 if (reg->mem_type == TTM_PL_TT)
42 return NvDmaTT;42 return NvDmaTT;
@@ -45,7 +45,7 @@ nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, · 2 unmodified lines
45 45
46int46int
47nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,47nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
48 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)48 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
49{49{
50 struct nvif_push *push = chan->chan.push;50 struct nvif_push *push = chan->chan.push;
51 u32 src_ctxdma = nouveau_bo_mem_ctxdma(bo, chan, old_reg);51 u32 src_ctxdma = nouveau_bo_mem_ctxdma(bo, chan, old_reg);
drivers/gpu/drm/nouveau/nouveau_bo5039.c+1−1
@@ -37,7 +37,7 @@ · 36 unmodified lines
37 37
38int38int
39nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,39nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
40 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)40 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
41{41{
42 struct nouveau_mem *mem = nouveau_mem(old_reg);42 struct nouveau_mem *mem = nouveau_mem(old_reg);
43 struct nvif_push *push = chan->chan.push;43 struct nvif_push *push = chan->chan.push;
drivers/gpu/drm/nouveau/nouveau_bo74c1.c+1−1
@@ -34,7 +34,7 @@ · 33 unmodified lines
34 34
35int35int
36nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,36nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
37 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)37 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
38{38{
39 struct nouveau_mem *mem = nouveau_mem(old_reg);39 struct nouveau_mem *mem = nouveau_mem(old_reg);
40 struct nvif_push *push = chan->chan.push;40 struct nvif_push *push = chan->chan.push;
drivers/gpu/drm/nouveau/nouveau_bo85b5.c+1−1
@@ -38,7 +38,7 @@ · 37 unmodified lines
38 38
39int39int
40nva3_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,40nva3_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
41 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)41 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
42{42{
43 struct nouveau_mem *mem = nouveau_mem(old_reg);43 struct nouveau_mem *mem = nouveau_mem(old_reg);
44 struct nvif_push *push = chan->chan.push;44 struct nvif_push *push = chan->chan.push;
drivers/gpu/drm/nouveau/nouveau_bo9039.c+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
36 36
37int37int
38nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,38nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
39 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)39 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
40{40{
41 struct nvif_push *push = chan->chan.push;41 struct nvif_push *push = chan->chan.push;
42 struct nouveau_mem *mem = nouveau_mem(old_reg);42 struct nouveau_mem *mem = nouveau_mem(old_reg);
drivers/gpu/drm/nouveau/nouveau_bo90b5.c+1−1
@@ -31,7 +31,7 @@ · 30 unmodified lines
31 31
32int32int
33nvc0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,33nvc0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
34 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)34 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
35{35{
36 struct nouveau_mem *mem = nouveau_mem(old_reg);36 struct nouveau_mem *mem = nouveau_mem(old_reg);
37 struct nvif_push *push = chan->chan.push;37 struct nvif_push *push = chan->chan.push;
drivers/gpu/drm/nouveau/nouveau_boa0b5.c+1−1
@@ -36,7 +36,7 @@ · 35 unmodified lines
36 36
37int37int
38nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,38nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
39 struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)39 struct ttm_resource *old_reg, struct ttm_resource *new_reg)
40{40{
41 struct nouveau_mem *mem = nouveau_mem(old_reg);41 struct nouveau_mem *mem = nouveau_mem(old_reg);
42 struct nvif_push *push = chan->chan.push;42 struct nvif_push *push = chan->chan.push;
drivers/gpu/drm/nouveau/nouveau_drv.h+1−1
@@ -157,7 +157,7 @@ struct nouveau_drm { · 156 unmodified lines
157 atomic_t validate_sequence;157 atomic_t validate_sequence;
158 int (*move)(struct nouveau_channel *,158 int (*move)(struct nouveau_channel *,
159 struct ttm_buffer_object *,159 struct ttm_buffer_object *,
160 struct ttm_mem_reg *, struct ttm_mem_reg *);160 struct ttm_resource *, struct ttm_resource *);
161 struct nouveau_channel *chan;161 struct nouveau_channel *chan;
162 struct nvif_object copy;162 struct nvif_object copy;
163 int mtrr;163 int mtrr;
drivers/gpu/drm/nouveau/nouveau_mem.c+4−4
@@ -92,7 +92,7 @@ nouveau_mem_fini(struct nouveau_mem *mem) · 91 unmodified lines
92}92}
93 93
94int94int
95nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt)95nouveau_mem_host(struct ttm_resource *reg, struct ttm_dma_tt *tt)
96{96{
97 struct nouveau_mem *mem = nouveau_mem(reg);97 struct nouveau_mem *mem = nouveau_mem(reg);
98 struct nouveau_cli *cli = mem->cli;98 struct nouveau_cli *cli = mem->cli;
@@ -130,7 +130,7 @@ nouveau_mem_host(struct ttm_mem_reg *reg, struct ttm_dma_tt *tt) · 31 unmodified lines
130}130}
131 131
132int132int
133nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page)133nouveau_mem_vram(struct ttm_resource *reg, bool contig, u8 page)
134{134{
135 struct nouveau_mem *mem = nouveau_mem(reg);135 struct nouveau_mem *mem = nouveau_mem(reg);
136 struct nouveau_cli *cli = mem->cli;136 struct nouveau_cli *cli = mem->cli;
@@ -173,7 +173,7 @@ nouveau_mem_vram(struct ttm_mem_reg *reg, bool contig, u8 page) · 36 unmodified lines
173}173}
174 174
175void175void
176nouveau_mem_del(struct ttm_mem_reg *reg)176nouveau_mem_del(struct ttm_resource *reg)
177{177{
178 struct nouveau_mem *mem = nouveau_mem(reg);178 struct nouveau_mem *mem = nouveau_mem(reg);
179 nouveau_mem_fini(mem);179 nouveau_mem_fini(mem);
@@ -183,7 +183,7 @@ nouveau_mem_del(struct ttm_mem_reg *reg) · 3 unmodified lines
183 183
184int184int
185nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp,185nouveau_mem_new(struct nouveau_cli *cli, u8 kind, u8 comp,
186 struct ttm_mem_reg *reg)186 struct ttm_resource *reg)
187{187{
188 struct nouveau_mem *mem;188 struct nouveau_mem *mem;
189 189
drivers/gpu/drm/nouveau/nouveau_mem.h+5−5
@@ -7,7 +7,7 @@ struct ttm_dma_tt; · 6 unmodified lines
7#include <nvif/vmm.h>7#include <nvif/vmm.h>
8 8
9static inline struct nouveau_mem *9static inline struct nouveau_mem *
10nouveau_mem(struct ttm_mem_reg *reg)10nouveau_mem(struct ttm_resource *reg)
11{11{
12 return reg->mm_node;12 return reg->mm_node;
13}13}
@@ -21,10 +21,10 @@ struct nouveau_mem { · 7 unmodified lines
21};21};
22 22
23int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,23int nouveau_mem_new(struct nouveau_cli *, u8 kind, u8 comp,
24 struct ttm_mem_reg *);24 struct ttm_resource *);
25void nouveau_mem_del(struct ttm_mem_reg *);25void nouveau_mem_del(struct ttm_resource *);
26int nouveau_mem_vram(struct ttm_mem_reg *, bool contig, u8 page);26int nouveau_mem_vram(struct ttm_resource *, bool contig, u8 page);
27int nouveau_mem_host(struct ttm_mem_reg *, struct ttm_dma_tt *);27int nouveau_mem_host(struct ttm_resource *, struct ttm_dma_tt *);
28void nouveau_mem_fini(struct nouveau_mem *);28void nouveau_mem_fini(struct nouveau_mem *);
29int nouveau_mem_map(struct nouveau_mem *, struct nvif_vmm *, struct nvif_vma *);29int nouveau_mem_map(struct nouveau_mem *, struct nvif_vmm *, struct nvif_vma *);
30#endif30#endif
drivers/gpu/drm/nouveau/nouveau_sgdma.c+2−2
@@ -26,7 +26,7 @@ nouveau_sgdma_destroy(struct ttm_tt *ttm) · 25 unmodified lines
26}26}
27 27
28static int28static int
29nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg)29nv04_sgdma_bind(struct ttm_tt *ttm, struct ttm_resource *reg)
30{30{
31 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;31 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
32 struct nouveau_mem *mem = nouveau_mem(reg);32 struct nouveau_mem *mem = nouveau_mem(reg);
@@ -60,7 +60,7 @@ static struct ttm_backend_func nv04_sgdma_backend = { · 27 unmodified lines
60};60};
61 61
62static int62static int
63nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_mem_reg *reg)63nv50_sgdma_bind(struct ttm_tt *ttm, struct ttm_resource *reg)
64{64{
65 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;65 struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)ttm;
66 struct nouveau_mem *mem = nouveau_mem(reg);66 struct nouveau_mem *mem = nouveau_mem(reg);
drivers/gpu/drm/nouveau/nouveau_ttm.c+127−49
@@ -31,35 +31,17 @@ · 30 unmodified lines
31 31
32#include <core/tegra.h>32#include <core/tegra.h>
33 33
34static int
35nouveau_manager_init(struct ttm_mem_type_manager *man, unsigned long psize)
36{
37 return 0;
38}
39
40static int
41nouveau_manager_fini(struct ttm_mem_type_manager *man)
42{
43 return 0;
44}
45
46static void34static void
47nouveau_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *reg)35nouveau_manager_del(struct ttm_resource_manager *man, struct ttm_resource *reg)
48{36{
49 nouveau_mem_del(reg);37 nouveau_mem_del(reg);
50}38}
51 39
52static void
53nouveau_manager_debug(struct ttm_mem_type_manager *man,
54 struct drm_printer *printer)
55{
56}
57
58static int40static int
59nouveau_vram_manager_new(struct ttm_mem_type_manager *man,41nouveau_vram_manager_new(struct ttm_resource_manager *man,
60 struct ttm_buffer_object *bo,42 struct ttm_buffer_object *bo,
61 const struct ttm_place *place,43 const struct ttm_place *place,
62 struct ttm_mem_reg *reg)44 struct ttm_resource *reg)
63{45{
64 struct nouveau_bo *nvbo = nouveau_bo(bo);46 struct nouveau_bo *nvbo = nouveau_bo(bo);
65 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);47 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
@@ -81,19 +63,16 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, · 15 unmodified lines
81 return 0;63 return 0;
82}64}
83 65
84const struct ttm_mem_type_manager_func nouveau_vram_manager = {66const struct ttm_resource_manager_func nouveau_vram_manager = {
85 .init = nouveau_manager_init,67 .alloc = nouveau_vram_manager_new,
86 .takedown = nouveau_manager_fini,68 .free = nouveau_manager_del,
87 .get_node = nouveau_vram_manager_new,
88 .put_node = nouveau_manager_del,
89 .debug = nouveau_manager_debug,
90};69};
91 70
92static int71static int
93nouveau_gart_manager_new(struct ttm_mem_type_manager *man,72nouveau_gart_manager_new(struct ttm_resource_manager *man,
94 struct ttm_buffer_object *bo,73 struct ttm_buffer_object *bo,
95 const struct ttm_place *place,74 const struct ttm_place *place,
96 struct ttm_mem_reg *reg)75 struct ttm_resource *reg)
97{76{
98 struct nouveau_bo *nvbo = nouveau_bo(bo);77 struct nouveau_bo *nvbo = nouveau_bo(bo);
99 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);78 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
@@ -107,19 +86,16 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man, · 7 unmodified lines
107 return 0;86 return 0;
108}87}
109 88
110const struct ttm_mem_type_manager_func nouveau_gart_manager = {89const struct ttm_resource_manager_func nouveau_gart_manager = {
111 .init = nouveau_manager_init,90 .alloc = nouveau_gart_manager_new,
112 .takedown = nouveau_manager_fini,91 .free = nouveau_manager_del,
113 .get_node = nouveau_gart_manager_new,
114 .put_node = nouveau_manager_del,
115 .debug = nouveau_manager_debug
116};92};
117 93
118static int94static int
119nv04_gart_manager_new(struct ttm_mem_type_manager *man,95nv04_gart_manager_new(struct ttm_resource_manager *man,
120 struct ttm_buffer_object *bo,96 struct ttm_buffer_object *bo,
121 const struct ttm_place *place,97 const struct ttm_place *place,
122 struct ttm_mem_reg *reg)98 struct ttm_resource *reg)
123{99{
124 struct nouveau_bo *nvbo = nouveau_bo(bo);100 struct nouveau_bo *nvbo = nouveau_bo(bo);
125 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);101 struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
@@ -142,12 +118,9 @@ nv04_gart_manager_new(struct ttm_mem_type_manager *man, · 16 unmodified lines
142 return 0;118 return 0;
143}119}
144 120
145const struct ttm_mem_type_manager_func nv04_gart_manager = {121const struct ttm_resource_manager_func nv04_gart_manager = {
146 .init = nouveau_manager_init,122 .alloc = nv04_gart_manager_new,
147 .takedown = nouveau_manager_fini,123 .free = nouveau_manager_del,
148 .get_node = nv04_gart_manager_new,
149 .put_node = nouveau_manager_del,
150 .debug = nouveau_manager_debug
151};124};
152 125
153int126int
@@ -180,6 +153,113 @@ nouveau_ttm_init_host(struct nouveau_drm *drm, u8 kind) · 26 unmodified lines
180 return 0;153 return 0;
181}154}
182 155
156static int
157nouveau_ttm_init_vram(struct nouveau_drm *drm)
158{
159 struct nvif_mmu *mmu = &drm->client.mmu;
160 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
161 /* Some BARs do not support being ioremapped WC */
162 const u8 type = mmu->type[drm->ttm.type_vram].type;
163 struct ttm_resource_manager *man = kzalloc(sizeof(*man), GFP_KERNEL);
164 if (!man)
165 return -ENOMEM;
166
167 man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
168 man->default_caching = TTM_PL_FLAG_WC;
169
170 if (type & NVIF_MEM_UNCACHED) {
171 man->available_caching = TTM_PL_FLAG_UNCACHED;
172 man->default_caching = TTM_PL_FLAG_UNCACHED;
173 }
174
175 man->func = &nouveau_vram_manager;
176 man->use_io_reserve_lru = true;
177
178 ttm_resource_manager_init(man,
179 drm->gem.vram_available >> PAGE_SHIFT);
180 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, man);
181 ttm_resource_manager_set_used(man, true);
182 return 0;
183 } else {
184 return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_VRAM,
185 TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
186 TTM_PL_FLAG_WC, false,
187 drm->gem.vram_available >> PAGE_SHIFT);
188 }
189}
190
191static void
192nouveau_ttm_fini_vram(struct nouveau_drm *drm)
193{
194 struct ttm_resource_manager *man = ttm_manager_type(&drm->ttm.bdev, TTM_PL_VRAM);
195
196 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA) {
197 ttm_resource_manager_set_used(man, false);
198 ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man);
199 ttm_resource_manager_cleanup(man);
200 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_VRAM, NULL);
201 kfree(man);
202 } else
203 ttm_range_man_fini(&drm->ttm.bdev, TTM_PL_VRAM);
204}
205
206static int
207nouveau_ttm_init_gtt(struct nouveau_drm *drm)
208{
209 struct ttm_resource_manager *man;
210 unsigned long size_pages = drm->gem.gart_available >> PAGE_SHIFT;
211 unsigned available_caching, default_caching;
212 const struct ttm_resource_manager_func *func = NULL;
213 if (drm->agp.bridge) {
214 available_caching = TTM_PL_FLAG_UNCACHED |
215 TTM_PL_FLAG_WC;
216 default_caching = TTM_PL_FLAG_WC;
217 } else {
218 available_caching = TTM_PL_MASK_CACHING;
219 default_caching = TTM_PL_FLAG_CACHED;
220 }
221
222 if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA)
223 func = &nouveau_gart_manager;
224 else if (!drm->agp.bridge)
225 func = &nv04_gart_manager;
226 else
227 return ttm_range_man_init(&drm->ttm.bdev, TTM_PL_TT,
228 available_caching, default_caching,
229 true,
230 size_pages);
231
232 man = kzalloc(sizeof(*man), GFP_KERNEL);
233 if (!man)
234 return -ENOMEM;
235
236 man->func = func;
237 man->available_caching = available_caching;
238 man->default_caching = default_caching;
239 man->use_tt = true;
240 ttm_resource_manager_init(man, size_pages);
241 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, man);
242 ttm_resource_manager_set_used(man, true);
243 return 0;
244}
245
246static void
247nouveau_ttm_fini_gtt(struct nouveau_drm *drm)
248{
249 struct ttm_resource_manager *man = ttm_manager_type(&drm->ttm.bdev, TTM_PL_TT);
250
251 if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA &&
252 drm->agp.bridge)
253 ttm_range_man_fini(&drm->ttm.bdev, TTM_PL_TT);
254 else {
255 ttm_resource_manager_set_used(man, false);
256 ttm_resource_manager_force_list_clean(&drm->ttm.bdev, man);
257 ttm_resource_manager_cleanup(man);
258 ttm_set_driver_manager(&drm->ttm.bdev, TTM_PL_TT, NULL);
259 kfree(man);
260 }
261}
262
183int263int
184nouveau_ttm_init(struct nouveau_drm *drm)264nouveau_ttm_init(struct nouveau_drm *drm)
185{265{
@@ -237,8 +317,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) · 51 unmodified lines
237 arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1),317 arch_io_reserve_memtype_wc(device->func->resource_addr(device, 1),
238 device->func->resource_size(device, 1));318 device->func->resource_size(device, 1));
239 319
240 ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_VRAM,320 ret = nouveau_ttm_init_vram(drm);
241 drm->gem.vram_available >> PAGE_SHIFT);
242 if (ret) {321 if (ret) {
243 NV_ERROR(drm, "VRAM mm init failed, %d\n", ret);322 NV_ERROR(drm, "VRAM mm init failed, %d\n", ret);
244 return ret;323 return ret;
@@ -254,8 +333,7 @@ nouveau_ttm_init(struct nouveau_drm *drm) · 9 unmodified lines
254 drm->gem.gart_available = drm->agp.size;333 drm->gem.gart_available = drm->agp.size;
255 }334 }
256 335
257 ret = ttm_bo_init_mm(&drm->ttm.bdev, TTM_PL_TT,336 ret = nouveau_ttm_init_gtt(drm);
258 drm->gem.gart_available >> PAGE_SHIFT);
259 if (ret) {337 if (ret) {
260 NV_ERROR(drm, "GART mm init failed, %d\n", ret);338 NV_ERROR(drm, "GART mm init failed, %d\n", ret);
261 return ret;339 return ret;
@@ -271,8 +349,8 @@ nouveau_ttm_fini(struct nouveau_drm *drm) · 9 unmodified lines
271{349{
272 struct nvkm_device *device = nvxx_device(&drm->client.device);350 struct nvkm_device *device = nvxx_device(&drm->client.device);
273 351
274 ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_VRAM);352 nouveau_ttm_fini_vram(drm);
275 ttm_bo_clean_mm(&drm->ttm.bdev, TTM_PL_TT);353 nouveau_ttm_fini_gtt(drm);
276 354
277 ttm_bo_device_release(&drm->ttm.bdev);355 ttm_bo_device_release(&drm->ttm.bdev);
278 356
drivers/gpu/drm/nouveau/nouveau_ttm.h+3−3
@@ -8,9 +8,9 @@ nouveau_bdev(struct ttm_bo_device *bd) · 7 unmodified lines
8 return container_of(bd, struct nouveau_drm, ttm.bdev);8 return container_of(bd, struct nouveau_drm, ttm.bdev);
9}9}
10 10
11extern const struct ttm_mem_type_manager_func nouveau_vram_manager;11extern const struct ttm_resource_manager_func nouveau_vram_manager;
12extern const struct ttm_mem_type_manager_func nouveau_gart_manager;12extern const struct ttm_resource_manager_func nouveau_gart_manager;
13extern const struct ttm_mem_type_manager_func nv04_gart_manager;13extern const struct ttm_resource_manager_func nv04_gart_manager;
14 14
15struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo,15struct ttm_tt *nouveau_sgdma_create_ttm(struct ttm_buffer_object *bo,
16 u32 page_flags);16 u32 page_flags);
drivers/gpu/drm/nouveau/nv17_fence.c+1−1
@@ -78,7 +78,7 @@ nv17_fence_context_new(struct nouveau_channel *chan) · 77 unmodified lines
78{78{
79 struct nv10_fence_priv *priv = chan->drm->fence;79 struct nv10_fence_priv *priv = chan->drm->fence;
80 struct nv10_fence_chan *fctx;80 struct nv10_fence_chan *fctx;
81 struct ttm_mem_reg *reg = &priv->bo->bo.mem;81 struct ttm_resource *reg = &priv->bo->bo.mem;
82 u32 start = reg->start * PAGE_SIZE;82 u32 start = reg->start * PAGE_SIZE;
83 u32 limit = start + reg->size - 1;83 u32 limit = start + reg->size - 1;
84 int ret = 0;84 int ret = 0;
drivers/gpu/drm/nouveau/nv50_fence.c+1−1
@@ -37,7 +37,7 @@ nv50_fence_context_new(struct nouveau_channel *chan) · 36 unmodified lines
37{37{
38 struct nv10_fence_priv *priv = chan->drm->fence;38 struct nv10_fence_priv *priv = chan->drm->fence;
39 struct nv10_fence_chan *fctx;39 struct nv10_fence_chan *fctx;
40 struct ttm_mem_reg *reg = &priv->bo->bo.mem;40 struct ttm_resource *reg = &priv->bo->bo.mem;
41 u32 start = reg->start * PAGE_SIZE;41 u32 start = reg->start * PAGE_SIZE;
42 u32 limit = start + reg->size - 1;42 u32 limit = start + reg->size - 1;
43 int ret;43 int ret;
drivers/gpu/drm/omapdrm/dss/hdmi4.c+0−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include <linux/platform_device.h>20#include <linux/platform_device.h>
21#include <linux/pm_runtime.h>21#include <linux/pm_runtime.h>
22#include <linux/clk.h>22#include <linux/clk.h>
23#include <linux/gpio.h>
24#include <linux/regulator/consumer.h>23#include <linux/regulator/consumer.h>
25#include <linux/component.h>24#include <linux/component.h>
26#include <linux/of.h>25#include <linux/of.h>
drivers/gpu/drm/omapdrm/dss/hdmi5.c+0−1
@@ -24,7 +24,6 @@ · 23 unmodified lines
24#include <linux/platform_device.h>24#include <linux/platform_device.h>
25#include <linux/pm_runtime.h>25#include <linux/pm_runtime.h>
26#include <linux/clk.h>26#include <linux/clk.h>
27#include <linux/gpio.h>
28#include <linux/regulator/consumer.h>27#include <linux/regulator/consumer.h>
29#include <linux/component.h>28#include <linux/component.h>
30#include <linux/of.h>29#include <linux/of.h>
drivers/gpu/drm/omapdrm/dss/venc.c+1−1
@@ -781,7 +781,7 @@ static int venc_probe_of(struct venc_device *venc) · 780 unmodified lines
781 venc->type = OMAP_DSS_VENC_TYPE_SVIDEO;781 venc->type = OMAP_DSS_VENC_TYPE_SVIDEO;
782 break;782 break;
783 default:783 default:
784 dev_err(&venc->pdev->dev, "bad channel propert '%d'\n",784 dev_err(&venc->pdev->dev, "bad channel property '%d'\n",
785 channels);785 channels);
786 r = -EINVAL;786 r = -EINVAL;
787 goto err;787 goto err;
drivers/gpu/drm/omapdrm/omap_drv.c+0−17
@@ -349,13 +349,6 @@ static int omap_modeset_init(struct drm_device *dev) · 348 unmodified lines
349 349
350 drm_connector_attach_encoder(pipe->connector, encoder);350 drm_connector_attach_encoder(pipe->connector, encoder);
351 351
352 if (pipe->output->panel) {
353 ret = drm_panel_attach(pipe->output->panel,
354 pipe->connector);
355 if (ret < 0)
356 return ret;
357 }
358
359 crtc = omap_crtc_init(dev, pipe, priv->planes[i]);352 crtc = omap_crtc_init(dev, pipe, priv->planes[i]);
360 if (IS_ERR(crtc))353 if (IS_ERR(crtc))
361 return PTR_ERR(crtc);354 return PTR_ERR(crtc);
@@ -394,18 +387,8 @@ static int omap_modeset_init(struct drm_device *dev) · 32 unmodified lines
394 387
395static void omap_modeset_fini(struct drm_device *ddev)388static void omap_modeset_fini(struct drm_device *ddev)
396{389{
397 struct omap_drm_private *priv = ddev->dev_private;
398 unsigned int i;
399
400 omap_drm_irq_uninstall(ddev);390 omap_drm_irq_uninstall(ddev);
401 391
402 for (i = 0; i < priv->num_pipes; i++) {
403 struct omap_drm_pipeline *pipe = &priv->pipes[i];
404
405 if (pipe->output->panel)
406 drm_panel_detach(pipe->output->panel);
407 }
408
409 drm_mode_config_cleanup(ddev);392 drm_mode_config_cleanup(ddev);
410}393}
411 394
drivers/gpu/drm/panel/Kconfig+11−0
@@ -217,6 +217,17 @@ config DRM_PANEL_NOVATEK_NT39016 · 216 unmodified lines
217 Say Y here if you want to enable support for the panels built217 Say Y here if you want to enable support for the panels built
218 around the Novatek NT39016 display controller.218 around the Novatek NT39016 display controller.
219 219
220config DRM_PANEL_MANTIX_MLAF057WE51
221 tristate "Mantix MLAF057WE51-X MIPI-DSI LCD panel"
222 depends on OF
223 depends on DRM_MIPI_DSI
224 depends on BACKLIGHT_CLASS_DEVICE
225 help
226 Say Y here if you want to enable support for the Mantix
227 MLAF057WE51-X MIPI DSI panel as e.g. used in the Librem 5. It
228 has a resolution of 720x1440 pixels, a built in backlight and touch
229 controller.
230
220config DRM_PANEL_OLIMEX_LCD_OLINUXINO231config DRM_PANEL_OLIMEX_LCD_OLINUXINO
221 tristate "Olimex LCD-OLinuXino panel"232 tristate "Olimex LCD-OLinuXino panel"
222 depends on OF233 depends on OF
drivers/gpu/drm/panel/Makefile+1−0
@@ -20,6 +20,7 @@ obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o · 19 unmodified lines
20obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o20obj-$(CONFIG_DRM_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o
21obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o21obj-$(CONFIG_DRM_PANEL_NOVATEK_NT35510) += panel-novatek-nt35510.o
22obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o22obj-$(CONFIG_DRM_PANEL_NOVATEK_NT39016) += panel-novatek-nt39016.o
23obj-$(CONFIG_DRM_PANEL_MANTIX_MLAF057WE51) += panel-mantix-mlaf057we51.o
23obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o24obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
24obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o25obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
25obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o26obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o
drivers/gpu/drm/panel/panel-arm-versatile.c+3−1
@@ -349,7 +349,9 @@ static int versatile_panel_probe(struct platform_device *pdev) · 348 unmodified lines
349 drm_panel_init(&vpanel->panel, dev, &versatile_panel_drm_funcs,349 drm_panel_init(&vpanel->panel, dev, &versatile_panel_drm_funcs,
350 DRM_MODE_CONNECTOR_DPI);350 DRM_MODE_CONNECTOR_DPI);
351 351
352 return drm_panel_add(&vpanel->panel);352 drm_panel_add(&vpanel->panel);
353
354 return 0;
353}355}
354 356
355static const struct of_device_id versatile_panel_match[] = {357static const struct of_device_id versatile_panel_match[] = {
drivers/gpu/drm/panel/panel-asus-z00t-tm5p5-n35596.c+1−5
@@ -315,11 +315,7 @@ static int tm5p5_nt35596_probe(struct mipi_dsi_device *dsi) · 314 unmodified lines
315 return ret;315 return ret;
316 }316 }
317 317
318 ret = drm_panel_add(&ctx->panel);318 drm_panel_add(&ctx->panel);
319 if (ret < 0) {
320 dev_err(dev, "Failed to add panel: %d\n", ret);
321 return ret;
322 }
323 319
324 ret = mipi_dsi_attach(dsi);320 ret = mipi_dsi_attach(dsi);
325 if (ret < 0) {321 if (ret < 0) {
drivers/gpu/drm/panel/panel-boe-himax8279d.c+18−30
@@ -19,7 +19,6 @@ · 18 unmodified lines
19#include <drm/drm_mipi_dsi.h>19#include <drm/drm_mipi_dsi.h>
20#include <drm/drm_modes.h>20#include <drm/drm_modes.h>
21#include <drm/drm_panel.h>21#include <drm/drm_panel.h>
22#include <drm/drm_print.h>
23 22
24#include <video/mipi_display.h>23#include <video/mipi_display.h>
25 24
@@ -93,8 +92,7 @@ static int boe_panel_disable(struct drm_panel *panel) · 67 unmodified lines
93 92
94 err = mipi_dsi_dcs_set_display_off(pinfo->link);93 err = mipi_dsi_dcs_set_display_off(pinfo->link);
95 if (err < 0) {94 if (err < 0) {
96 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",95 dev_err(panel->dev, "failed to set display off: %d\n", err);
97 err);
98 return err;96 return err;
99 }97 }
100 98
@@ -113,13 +111,11 @@ static int boe_panel_unprepare(struct drm_panel *panel) · 12 unmodified lines
113 111
114 err = mipi_dsi_dcs_set_display_off(pinfo->link);112 err = mipi_dsi_dcs_set_display_off(pinfo->link);
115 if (err < 0)113 if (err < 0)
116 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",114 dev_err(panel->dev, "failed to set display off: %d\n", err);
117 err);
118 115
119 err = mipi_dsi_dcs_enter_sleep_mode(pinfo->link);116 err = mipi_dsi_dcs_enter_sleep_mode(pinfo->link);
120 if (err < 0)117 if (err < 0)
121 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",118 dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
122 err);
123 119
124 /* sleep_mode_delay: 1ms - 2ms */120 /* sleep_mode_delay: 1ms - 2ms */
125 usleep_range(1000, 2000);121 usleep_range(1000, 2000);
@@ -163,15 +159,13 @@ static int boe_panel_prepare(struct drm_panel *panel) · 37 unmodified lines
163 /* send init code */159 /* send init code */
164 err = send_mipi_cmds(panel, pinfo->desc->on_cmds);160 err = send_mipi_cmds(panel, pinfo->desc->on_cmds);
165 if (err < 0) {161 if (err < 0) {
166 DRM_DEV_ERROR(panel->dev, "failed to send DCS Init Code: %d\n",162 dev_err(panel->dev, "failed to send DCS Init Code: %d\n", err);
167 err);
168 goto poweroff;163 goto poweroff;
169 }164 }
170 165
171 err = mipi_dsi_dcs_exit_sleep_mode(pinfo->link);166 err = mipi_dsi_dcs_exit_sleep_mode(pinfo->link);
172 if (err < 0) {167 if (err < 0) {
173 DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n",168 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
174 err);
175 goto poweroff;169 goto poweroff;
176 }170 }
177 171
@@ -180,8 +174,7 @@ static int boe_panel_prepare(struct drm_panel *panel) · 2 unmodified lines
180 174
181 err = mipi_dsi_dcs_set_display_on(pinfo->link);175 err = mipi_dsi_dcs_set_display_on(pinfo->link);
182 if (err < 0) {176 if (err < 0) {
183 DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n",177 dev_err(panel->dev, "failed to set display on: %d\n", err);
184 err);
185 goto poweroff;178 goto poweroff;
186 }179 }
187 180
@@ -209,8 +202,7 @@ static int boe_panel_enable(struct drm_panel *panel) · 21 unmodified lines
209 202
210 ret = mipi_dsi_dcs_set_display_on(pinfo->link);203 ret = mipi_dsi_dcs_set_display_on(pinfo->link);
211 if (ret < 0) {204 if (ret < 0) {
212 DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n",205 dev_err(panel->dev, "failed to set display on: %d\n", ret);
213 ret);
214 return ret;206 return ret;
215 }207 }
216 208
@@ -228,8 +220,8 @@ static int boe_panel_get_modes(struct drm_panel *panel, · 11 unmodified lines
228 220
229 mode = drm_mode_duplicate(connector->dev, m);221 mode = drm_mode_duplicate(connector->dev, m);
230 if (!mode) {222 if (!mode) {
231 DRM_DEV_ERROR(pinfo->base.dev, "failed to add mode %ux%u@%u\n",223 dev_err(pinfo->base.dev, "failed to add mode %ux%u@%u\n",
232 m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));224 m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));
233 return -ENOMEM;225 return -ENOMEM;
234 }226 }
235 227
@@ -865,8 +857,7 @@ static int panel_add(struct panel_info *pinfo) · 629 unmodified lines
865 if (IS_ERR(pinfo->pp18_gpio)) {857 if (IS_ERR(pinfo->pp18_gpio)) {
866 ret = PTR_ERR(pinfo->pp18_gpio);858 ret = PTR_ERR(pinfo->pp18_gpio);
867 if (ret != -EPROBE_DEFER)859 if (ret != -EPROBE_DEFER)
868 DRM_DEV_ERROR(dev, "failed to get pp18 gpio: %d\n",860 dev_err(dev, "failed to get pp18 gpio: %d\n", ret);
869 ret);
870 return ret;861 return ret;
871 }862 }
872 863
@@ -874,8 +865,7 @@ static int panel_add(struct panel_info *pinfo) · 1 unmodified line
874 if (IS_ERR(pinfo->pp33_gpio)) {865 if (IS_ERR(pinfo->pp33_gpio)) {
875 ret = PTR_ERR(pinfo->pp33_gpio);866 ret = PTR_ERR(pinfo->pp33_gpio);
876 if (ret != -EPROBE_DEFER)867 if (ret != -EPROBE_DEFER)
877 DRM_DEV_ERROR(dev, "failed to get pp33 gpio: %d\n",868 dev_err(dev, "failed to get pp33 gpio: %d\n", ret);
878 ret);
879 return ret;869 return ret;
880 }870 }
881 871
@@ -883,8 +873,7 @@ static int panel_add(struct panel_info *pinfo) · 1 unmodified line
883 if (IS_ERR(pinfo->enable_gpio)) {873 if (IS_ERR(pinfo->enable_gpio)) {
884 ret = PTR_ERR(pinfo->enable_gpio);874 ret = PTR_ERR(pinfo->enable_gpio);
885 if (ret != -EPROBE_DEFER)875 if (ret != -EPROBE_DEFER)
886 DRM_DEV_ERROR(dev, "failed to get enable gpio: %d\n",876 dev_err(dev, "failed to get enable gpio: %d\n", ret);
887 ret);
888 return ret;877 return ret;
889 }878 }
890 879
@@ -895,7 +884,9 @@ static int panel_add(struct panel_info *pinfo) · 4 unmodified lines
895 if (ret)884 if (ret)
896 return ret;885 return ret;
897 886
898 return drm_panel_add(&pinfo->base);887 drm_panel_add(&pinfo->base);
888
889 return 0;
899}890}
900 891
901static int panel_probe(struct mipi_dsi_device *dsi)892static int panel_probe(struct mipi_dsi_device *dsi)
@@ -935,18 +926,15 @@ static int panel_remove(struct mipi_dsi_device *dsi) · 33 unmodified lines
935 926
936 err = boe_panel_disable(&pinfo->base);927 err = boe_panel_disable(&pinfo->base);
937 if (err < 0)928 if (err < 0)
938 DRM_DEV_ERROR(&dsi->dev, "failed to disable panel: %d\n",929 dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
939 err);
940 930
941 err = boe_panel_unprepare(&pinfo->base);931 err = boe_panel_unprepare(&pinfo->base);
942 if (err < 0)932 if (err < 0)
943 DRM_DEV_ERROR(&dsi->dev, "failed to unprepare panel: %d\n",933 dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
944 err);
945 934
946 err = mipi_dsi_detach(dsi);935 err = mipi_dsi_detach(dsi);
947 if (err < 0)936 if (err < 0)
948 DRM_DEV_ERROR(&dsi->dev, "failed to detach from DSI host: %d\n",937 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
949 err);
950 938
951 drm_panel_remove(&pinfo->base);939 drm_panel_remove(&pinfo->base);
952 940
drivers/gpu/drm/panel/panel-boe-tv101wum-nl6.c+11−1
@@ -11,6 +11,7 @@ · 10 unmodified lines
11#include <linux/of_device.h>11#include <linux/of_device.h>
12#include <linux/regulator/consumer.h>12#include <linux/regulator/consumer.h>
13 13
14#include <drm/drm_connector.h>
14#include <drm/drm_crtc.h>15#include <drm/drm_crtc.h>
15#include <drm/drm_mipi_dsi.h>16#include <drm/drm_mipi_dsi.h>
16#include <drm/drm_panel.h>17#include <drm/drm_panel.h>
@@ -43,6 +44,7 @@ struct boe_panel { · 26 unmodified lines
43 44
44 const struct panel_desc *desc;45 const struct panel_desc *desc;
45 46
47 enum drm_panel_orientation orientation;
46 struct regulator *pp1800;48 struct regulator *pp1800;
47 struct regulator *avee;49 struct regulator *avee;
48 struct regulator *avdd;50 struct regulator *avdd;
@@ -740,6 +742,7 @@ static int boe_panel_get_modes(struct drm_panel *panel, · 691 unmodified lines
740 connector->display_info.width_mm = boe->desc->size.width_mm;742 connector->display_info.width_mm = boe->desc->size.width_mm;
741 connector->display_info.height_mm = boe->desc->size.height_mm;743 connector->display_info.height_mm = boe->desc->size.height_mm;
742 connector->display_info.bpc = boe->desc->bpc;744 connector->display_info.bpc = boe->desc->bpc;
745 drm_connector_set_panel_orientation(connector, boe->orientation);
743 746
744 return 1;747 return 1;
745}748}
@@ -779,6 +782,11 @@ static int boe_panel_add(struct boe_panel *boe) · 33 unmodified lines
779 782
780 drm_panel_init(&boe->base, dev, &boe_panel_funcs,783 drm_panel_init(&boe->base, dev, &boe_panel_funcs,
781 DRM_MODE_CONNECTOR_DSI);784 DRM_MODE_CONNECTOR_DSI);
785 err = of_drm_get_panel_orientation(dev->of_node, &boe->orientation);
786 if (err < 0) {
787 dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
788 return err;
789 }
782 790
783 err = drm_panel_of_backlight(&boe->base);791 err = drm_panel_of_backlight(&boe->base);
784 if (err)792 if (err)
@@ -787,7 +795,9 @@ static int boe_panel_add(struct boe_panel *boe) · 2 unmodified lines
787 boe->base.funcs = &boe_panel_funcs;795 boe->base.funcs = &boe_panel_funcs;
788 boe->base.dev = &boe->dsi->dev;796 boe->base.dev = &boe->dsi->dev;
789 797
790 return drm_panel_add(&boe->base);798 drm_panel_add(&boe->base);
799
800 return 0;
791}801}
792 802
793static int boe_panel_probe(struct mipi_dsi_device *dsi)803static int boe_panel_probe(struct mipi_dsi_device *dsi)
drivers/gpu/drm/panel/panel-elida-kd35t133.c+19−32
@@ -22,7 +22,6 @@ · 21 unmodified lines
22#include <drm/drm_mipi_dsi.h>22#include <drm/drm_mipi_dsi.h>
23#include <drm/drm_modes.h>23#include <drm/drm_modes.h>
24#include <drm/drm_panel.h>24#include <drm/drm_panel.h>
25#include <drm/drm_print.h>
26 25
27/* Manufacturer specific Commands send via DSI */26/* Manufacturer specific Commands send via DSI */
28#define KD35T133_CMD_INTERFACEMODECTRL 0xb027#define KD35T133_CMD_INTERFACEMODECTRL 0xb0
@@ -89,7 +88,7 @@ static int kd35t133_init_sequence(struct kd35t133 *ctx) · 60 unmodified lines
89 0xa9, 0x51, 0x2c, 0x82);88 0xa9, 0x51, 0x2c, 0x82);
90 mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_INVERT_MODE, NULL, 0);89 mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_INVERT_MODE, NULL, 0);
91 90
92 DRM_DEV_DEBUG_DRIVER(dev, "Panel init sequence done\n");91 dev_dbg(dev, "Panel init sequence done\n");
93 return 0;92 return 0;
94}93}
95 94
@@ -104,13 +103,11 @@ static int kd35t133_unprepare(struct drm_panel *panel) · 8 unmodified lines
104 103
105 ret = mipi_dsi_dcs_set_display_off(dsi);104 ret = mipi_dsi_dcs_set_display_off(dsi);
106 if (ret < 0)105 if (ret < 0)
107 DRM_DEV_ERROR(ctx->dev, "failed to set display off: %d\n",106 dev_err(ctx->dev, "failed to set display off: %d\n", ret);
108 ret);
109 107
110 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);108 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
111 if (ret < 0) {109 if (ret < 0) {
112 DRM_DEV_ERROR(ctx->dev, "failed to enter sleep mode: %d\n",110 dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret);
113 ret);
114 return ret;111 return ret;
115 }112 }
116 113
@@ -131,18 +128,16 @@ static int kd35t133_prepare(struct drm_panel *panel) · 14 unmodified lines
131 if (ctx->prepared)128 if (ctx->prepared)
132 return 0;129 return 0;
133 130
134 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");131 dev_dbg(ctx->dev, "Resetting the panel\n");
135 ret = regulator_enable(ctx->vdd);132 ret = regulator_enable(ctx->vdd);
136 if (ret < 0) {133 if (ret < 0) {
137 DRM_DEV_ERROR(ctx->dev,134 dev_err(ctx->dev, "Failed to enable vdd supply: %d\n", ret);
138 "Failed to enable vdd supply: %d\n", ret);
139 return ret;135 return ret;
140 }136 }
141 137
142 ret = regulator_enable(ctx->iovcc);138 ret = regulator_enable(ctx->iovcc);
143 if (ret < 0) {139 if (ret < 0) {
144 DRM_DEV_ERROR(ctx->dev,140 dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
145 "Failed to enable iovcc supply: %d\n", ret);
146 goto disable_vdd;141 goto disable_vdd;
147 }142 }
148 143
@@ -156,7 +151,7 @@ static int kd35t133_prepare(struct drm_panel *panel) · 7 unmodified lines
156 151
157 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);152 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
158 if (ret < 0) {153 if (ret < 0) {
159 DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);154 dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
160 goto disable_iovcc;155 goto disable_iovcc;
161 }156 }
162 157
@@ -164,14 +159,13 @@ static int kd35t133_prepare(struct drm_panel *panel) · 1 unmodified line
164 159
165 ret = kd35t133_init_sequence(ctx);160 ret = kd35t133_init_sequence(ctx);
166 if (ret < 0) {161 if (ret < 0) {
167 DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",162 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
168 ret);
169 goto disable_iovcc;163 goto disable_iovcc;
170 }164 }
171 165
172 ret = mipi_dsi_dcs_set_display_on(dsi);166 ret = mipi_dsi_dcs_set_display_on(dsi);
173 if (ret < 0) {167 if (ret < 0) {
174 DRM_DEV_ERROR(ctx->dev, "Failed to set display on: %d\n", ret);168 dev_err(ctx->dev, "Failed to set display on: %d\n", ret);
175 goto disable_iovcc;169 goto disable_iovcc;
176 }170 }
177 171
@@ -210,9 +204,9 @@ static int kd35t133_get_modes(struct drm_panel *panel, · 32 unmodified lines
210 204
211 mode = drm_mode_duplicate(connector->dev, &default_mode);205 mode = drm_mode_duplicate(connector->dev, &default_mode);
212 if (!mode) {206 if (!mode) {
213 DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n",207 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
214 default_mode.hdisplay, default_mode.vdisplay,208 default_mode.hdisplay, default_mode.vdisplay,
215 drm_mode_vrefresh(&default_mode));209 drm_mode_vrefresh(&default_mode));
216 return -ENOMEM;210 return -ENOMEM;
217 }211 }
218 212
@@ -244,7 +238,7 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) · 25 unmodified lines
244 238
245 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);239 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
246 if (IS_ERR(ctx->reset_gpio)) {240 if (IS_ERR(ctx->reset_gpio)) {
247 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");241 dev_err(dev, "cannot get reset gpio\n");
248 return PTR_ERR(ctx->reset_gpio);242 return PTR_ERR(ctx->reset_gpio);
249 }243 }
250 244
@@ -252,9 +246,7 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
252 if (IS_ERR(ctx->vdd)) {246 if (IS_ERR(ctx->vdd)) {
253 ret = PTR_ERR(ctx->vdd);247 ret = PTR_ERR(ctx->vdd);
254 if (ret != -EPROBE_DEFER)248 if (ret != -EPROBE_DEFER)
255 DRM_DEV_ERROR(dev,249 dev_err(dev, "Failed to request vdd regulator: %d\n", ret);
256 "Failed to request vdd regulator: %d\n",
257 ret);
258 return ret;250 return ret;
259 }251 }
260 252
@@ -262,9 +254,7 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
262 if (IS_ERR(ctx->iovcc)) {254 if (IS_ERR(ctx->iovcc)) {
263 ret = PTR_ERR(ctx->iovcc);255 ret = PTR_ERR(ctx->iovcc);
264 if (ret != -EPROBE_DEFER)256 if (ret != -EPROBE_DEFER)
265 DRM_DEV_ERROR(dev,257 dev_err(dev, "Failed to request iovcc regulator: %d\n", ret);
266 "Failed to request iovcc regulator: %d\n",
267 ret);
268 return ret;258 return ret;
269 }259 }
270 260
@@ -288,7 +278,7 @@ static int kd35t133_probe(struct mipi_dsi_device *dsi) · 17 unmodified lines
288 278
289 ret = mipi_dsi_attach(dsi);279 ret = mipi_dsi_attach(dsi);
290 if (ret < 0) {280 if (ret < 0) {
291 DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret);281 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
292 drm_panel_remove(&ctx->panel);282 drm_panel_remove(&ctx->panel);
293 return ret;283 return ret;
294 }284 }
@@ -303,13 +293,11 @@ static void kd35t133_shutdown(struct mipi_dsi_device *dsi) · 8 unmodified lines
303 293
304 ret = drm_panel_unprepare(&ctx->panel);294 ret = drm_panel_unprepare(&ctx->panel);
305 if (ret < 0)295 if (ret < 0)
306 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",296 dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
307 ret);
308 297
309 ret = drm_panel_disable(&ctx->panel);298 ret = drm_panel_disable(&ctx->panel);
310 if (ret < 0)299 if (ret < 0)
311 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",300 dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
312 ret);
313}301}
314 302
315static int kd35t133_remove(struct mipi_dsi_device *dsi)303static int kd35t133_remove(struct mipi_dsi_device *dsi)
@@ -321,8 +309,7 @@ static int kd35t133_remove(struct mipi_dsi_device *dsi) · 5 unmodified lines
321 309
322 ret = mipi_dsi_detach(dsi);310 ret = mipi_dsi_detach(dsi);
323 if (ret < 0)311 if (ret < 0)
324 DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",312 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
325 ret);
326 313
327 drm_panel_remove(&ctx->panel);314 drm_panel_remove(&ctx->panel);
328 315
drivers/gpu/drm/panel/panel-feixin-k101-im2ba02.c+9−14
@@ -13,7 +13,6 @@ · 12 unmodified lines
13#include <drm/drm_mipi_dsi.h>13#include <drm/drm_mipi_dsi.h>
14#include <drm/drm_modes.h>14#include <drm/drm_modes.h>
15#include <drm/drm_panel.h>15#include <drm/drm_panel.h>
16#include <drm/drm_print.h>
17 16
18#define K101_IM2BA02_INIT_CMD_LEN 217#define K101_IM2BA02_INIT_CMD_LEN 2
19 18
@@ -374,13 +373,11 @@ static int k101_im2ba02_unprepare(struct drm_panel *panel) · 354 unmodified lines
374 373
375 ret = mipi_dsi_dcs_set_display_off(ctx->dsi);374 ret = mipi_dsi_dcs_set_display_off(ctx->dsi);
376 if (ret < 0)375 if (ret < 0)
377 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",376 dev_err(panel->dev, "failed to set display off: %d\n", ret);
378 ret);
379 377
380 ret = mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);378 ret = mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
381 if (ret < 0)379 if (ret < 0)
382 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",380 dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
383 ret);
384 381
385 msleep(200);382 msleep(200);
386 383
@@ -416,10 +413,10 @@ static int k101_im2ba02_get_modes(struct drm_panel *panel, · 29 unmodified lines
416 413
417 mode = drm_mode_duplicate(connector->dev, &k101_im2ba02_default_mode);414 mode = drm_mode_duplicate(connector->dev, &k101_im2ba02_default_mode);
418 if (!mode) {415 if (!mode) {
419 DRM_DEV_ERROR(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",416 dev_err(&ctx->dsi->dev, "failed to add mode %ux%u@%u\n",
420 k101_im2ba02_default_mode.hdisplay,417 k101_im2ba02_default_mode.hdisplay,
421 k101_im2ba02_default_mode.vdisplay,418 k101_im2ba02_default_mode.vdisplay,
422 drm_mode_vrefresh(&k101_im2ba02_default_mode));419 drm_mode_vrefresh(&k101_im2ba02_default_mode));
423 return -ENOMEM;420 return -ENOMEM;
424 }421 }
425 422
@@ -460,13 +457,13 @@ static int k101_im2ba02_dsi_probe(struct mipi_dsi_device *dsi) · 34 unmodified lines
460 ret = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ctx->supplies),457 ret = devm_regulator_bulk_get(&dsi->dev, ARRAY_SIZE(ctx->supplies),
461 ctx->supplies);458 ctx->supplies);
462 if (ret < 0) {459 if (ret < 0) {
463 DRM_DEV_ERROR(&dsi->dev, "Couldn't get regulators\n");460 dev_err(&dsi->dev, "Couldn't get regulators\n");
464 return ret;461 return ret;
465 }462 }
466 463
467 ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);464 ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
468 if (IS_ERR(ctx->reset)) {465 if (IS_ERR(ctx->reset)) {
469 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our reset GPIO\n");466 dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
470 return PTR_ERR(ctx->reset);467 return PTR_ERR(ctx->reset);
471 }468 }
472 469
@@ -477,9 +474,7 @@ static int k101_im2ba02_dsi_probe(struct mipi_dsi_device *dsi) · 4 unmodified lines
477 if (ret)474 if (ret)
478 return ret;475 return ret;
479 476
480 ret = drm_panel_add(&ctx->panel);477 drm_panel_add(&ctx->panel);
481 if (ret < 0)
482 return ret;
483 478
484 dsi->mode_flags = MIPI_DSI_MODE_VIDEO;479 dsi->mode_flags = MIPI_DSI_MODE_VIDEO;
485 dsi->format = MIPI_DSI_FMT_RGB888;480 dsi->format = MIPI_DSI_FMT_RGB888;
drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c+10−15
@@ -7,7 +7,6 @@ · 6 unmodified lines
7#include <drm/drm_mipi_dsi.h>7#include <drm/drm_mipi_dsi.h>
8#include <drm/drm_modes.h>8#include <drm/drm_modes.h>
9#include <drm/drm_panel.h>9#include <drm/drm_panel.h>
10#include <drm/drm_print.h>
11 10
12#include <linux/gpio/consumer.h>11#include <linux/gpio/consumer.h>
13#include <linux/delay.h>12#include <linux/delay.h>
@@ -118,13 +117,11 @@ static int feiyang_unprepare(struct drm_panel *panel) · 104 unmodified lines
118 117
119 ret = mipi_dsi_dcs_set_display_off(ctx->dsi);118 ret = mipi_dsi_dcs_set_display_off(ctx->dsi);
120 if (ret < 0)119 if (ret < 0)
121 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",120 dev_err(panel->dev, "failed to set display off: %d\n", ret);
122 ret);
123 121
124 ret = mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);122 ret = mipi_dsi_dcs_enter_sleep_mode(ctx->dsi);
125 if (ret < 0)123 if (ret < 0)
126 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",124 dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
127 ret);
128 125
129 /* T13 (backlight fall + video & logic signal fall) T13 >= 200ms */126 /* T13 (backlight fall + video & logic signal fall) T13 >= 200ms */
130 msleep(200);127 msleep(200);
@@ -165,10 +162,10 @@ static int feiyang_get_modes(struct drm_panel *panel, · 34 unmodified lines
165 162
166 mode = drm_mode_duplicate(connector->dev, &feiyang_default_mode);163 mode = drm_mode_duplicate(connector->dev, &feiyang_default_mode);
167 if (!mode) {164 if (!mode) {
168 DRM_DEV_ERROR(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",165 dev_err(&ctx->dsi->dev, "failed to add mode %ux%u@%u\n",
169 feiyang_default_mode.hdisplay,166 feiyang_default_mode.hdisplay,
170 feiyang_default_mode.vdisplay,167 feiyang_default_mode.vdisplay,
171 drm_mode_vrefresh(&feiyang_default_mode));168 drm_mode_vrefresh(&feiyang_default_mode));
172 return -ENOMEM;169 return -ENOMEM;
173 }170 }
174 171
@@ -204,19 +201,19 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi) · 29 unmodified lines
204 201
205 ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd");202 ctx->dvdd = devm_regulator_get(&dsi->dev, "dvdd");
206 if (IS_ERR(ctx->dvdd)) {203 if (IS_ERR(ctx->dvdd)) {
207 DRM_DEV_ERROR(&dsi->dev, "Couldn't get dvdd regulator\n");204 dev_err(&dsi->dev, "Couldn't get dvdd regulator\n");
208 return PTR_ERR(ctx->dvdd);205 return PTR_ERR(ctx->dvdd);
209 }206 }
210 207
211 ctx->avdd = devm_regulator_get(&dsi->dev, "avdd");208 ctx->avdd = devm_regulator_get(&dsi->dev, "avdd");
212 if (IS_ERR(ctx->avdd)) {209 if (IS_ERR(ctx->avdd)) {
213 DRM_DEV_ERROR(&dsi->dev, "Couldn't get avdd regulator\n");210 dev_err(&dsi->dev, "Couldn't get avdd regulator\n");
214 return PTR_ERR(ctx->avdd);211 return PTR_ERR(ctx->avdd);
215 }212 }
216 213
217 ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);214 ctx->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
218 if (IS_ERR(ctx->reset)) {215 if (IS_ERR(ctx->reset)) {
219 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our reset GPIO\n");216 dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
220 return PTR_ERR(ctx->reset);217 return PTR_ERR(ctx->reset);
221 }218 }
222 219
@@ -224,9 +221,7 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
224 if (ret)221 if (ret)
225 return ret;222 return ret;
226 223
227 ret = drm_panel_add(&ctx->panel);224 drm_panel_add(&ctx->panel);
228 if (ret < 0)
229 return ret;
230 225
231 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;226 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_BURST;
232 dsi->format = MIPI_DSI_FMT_RGB888;227 dsi->format = MIPI_DSI_FMT_RGB888;
drivers/gpu/drm/panel/panel-ilitek-ili9322.c+4−3
@@ -33,7 +33,6 @@ · 32 unmodified lines
33 33
34#include <drm/drm_modes.h>34#include <drm/drm_modes.h>
35#include <drm/drm_panel.h>35#include <drm/drm_panel.h>
36#include <drm/drm_print.h>
37 36
38#define ILI9322_CHIP_ID 0x0037#define ILI9322_CHIP_ID 0x00
39#define ILI9322_CHIP_ID_MAGIC 0x9638#define ILI9322_CHIP_ID_MAGIC 0x96
@@ -683,7 +682,7 @@ static int ili9322_get_modes(struct drm_panel *panel, · 643 unmodified lines
683 break;682 break;
684 }683 }
685 if (!mode) {684 if (!mode) {
686 DRM_ERROR("bad mode or failed to add mode\n");685 dev_err(panel->dev, "bad mode or failed to add mode\n");
687 return -EINVAL;686 return -EINVAL;
688 }687 }
689 drm_mode_set_name(mode);688 drm_mode_set_name(mode);
@@ -892,7 +891,9 @@ static int ili9322_probe(struct spi_device *spi) · 202 unmodified lines
892 drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs,891 drm_panel_init(&ili->panel, dev, &ili9322_drm_funcs,
893 DRM_MODE_CONNECTOR_DPI);892 DRM_MODE_CONNECTOR_DPI);
894 893
895 return drm_panel_add(&ili->panel);894 drm_panel_add(&ili->panel);
895
896 return 0;
896}897}
897 898
898static int ili9322_remove(struct spi_device *spi)899static int ili9322_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-ilitek-ili9881c.c+255−22
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/fb.h>10#include <linux/fb.h>
11#include <linux/kernel.h>11#include <linux/kernel.h>
12#include <linux/module.h>12#include <linux/module.h>
13#include <linux/of_device.h>
13 14
14#include <linux/gpio/consumer.h>15#include <linux/gpio/consumer.h>
15#include <linux/regulator/consumer.h>16#include <linux/regulator/consumer.h>
@@ -20,14 +21,6 @@ · 4 unmodified lines
20 21
21#include <video/mipi_display.h>22#include <video/mipi_display.h>
22 23
23struct ili9881c {
24 struct drm_panel panel;
25 struct mipi_dsi_device *dsi;
26
27 struct regulator *power;
28 struct gpio_desc *reset;
29};
30
31enum ili9881c_op {24enum ili9881c_op {
32 ILI9881C_SWITCH_PAGE,25 ILI9881C_SWITCH_PAGE,
33 ILI9881C_COMMAND,26 ILI9881C_COMMAND,
@@ -45,6 +38,21 @@ struct ili9881c_instr { · 11 unmodified lines
45 } arg;38 } arg;
46};39};
47 40
41struct ili9881c_desc {
42 const struct ili9881c_instr *init;
43 const size_t init_length;
44 const struct drm_display_mode *mode;
45};
46
47struct ili9881c {
48 struct drm_panel panel;
49 struct mipi_dsi_device *dsi;
50 const struct ili9881c_desc *desc;
51
52 struct regulator *power;
53 struct gpio_desc *reset;
54};
55
48#define ILI9881C_SWITCH_PAGE_INSTR(_page) \56#define ILI9881C_SWITCH_PAGE_INSTR(_page) \
49 { \57 { \
50 .op = ILI9881C_SWITCH_PAGE, \58 .op = ILI9881C_SWITCH_PAGE, \
@@ -64,7 +72,7 @@ struct ili9881c_instr { · 13 unmodified lines
64 }, \72 }, \
65 }73 }
66 74
67static const struct ili9881c_instr ili9881c_init[] = {75static const struct ili9881c_instr lhr050h41_init[] = {
68 ILI9881C_SWITCH_PAGE_INSTR(3),76 ILI9881C_SWITCH_PAGE_INSTR(3),
69 ILI9881C_COMMAND_INSTR(0x01, 0x00),77 ILI9881C_COMMAND_INSTR(0x01, 0x00),
70 ILI9881C_COMMAND_INSTR(0x02, 0x00),78 ILI9881C_COMMAND_INSTR(0x02, 0x00),
@@ -252,6 +260,199 @@ static const struct ili9881c_instr ili9881c_init[] = { · 181 unmodified lines
252 ILI9881C_COMMAND_INSTR(0xD3, 0x3F),260 ILI9881C_COMMAND_INSTR(0xD3, 0x3F),
253};261};
254 262
263static const struct ili9881c_instr k101_im2byl02_init[] = {
264 ILI9881C_SWITCH_PAGE_INSTR(3),
265 ILI9881C_COMMAND_INSTR(0x01, 0x00),
266 ILI9881C_COMMAND_INSTR(0x02, 0x00),
267 ILI9881C_COMMAND_INSTR(0x03, 0x73),
268 ILI9881C_COMMAND_INSTR(0x04, 0x00),
269 ILI9881C_COMMAND_INSTR(0x05, 0x00),
270 ILI9881C_COMMAND_INSTR(0x06, 0x08),
271 ILI9881C_COMMAND_INSTR(0x07, 0x00),
272 ILI9881C_COMMAND_INSTR(0x08, 0x00),
273 ILI9881C_COMMAND_INSTR(0x09, 0x00),
274 ILI9881C_COMMAND_INSTR(0x0A, 0x01),
275 ILI9881C_COMMAND_INSTR(0x0B, 0x01),
276 ILI9881C_COMMAND_INSTR(0x0C, 0x00),
277 ILI9881C_COMMAND_INSTR(0x0D, 0x01),
278 ILI9881C_COMMAND_INSTR(0x0E, 0x01),
279 ILI9881C_COMMAND_INSTR(0x0F, 0x00),
280 ILI9881C_COMMAND_INSTR(0x10, 0x00),
281 ILI9881C_COMMAND_INSTR(0x11, 0x00),
282 ILI9881C_COMMAND_INSTR(0x12, 0x00),
283 ILI9881C_COMMAND_INSTR(0x13, 0x00),
284 ILI9881C_COMMAND_INSTR(0x14, 0x00),
285 ILI9881C_COMMAND_INSTR(0x15, 0x00),
286 ILI9881C_COMMAND_INSTR(0x16, 0x00),
287 ILI9881C_COMMAND_INSTR(0x17, 0x00),
288 ILI9881C_COMMAND_INSTR(0x18, 0x00),
289 ILI9881C_COMMAND_INSTR(0x19, 0x00),
290 ILI9881C_COMMAND_INSTR(0x1A, 0x00),
291 ILI9881C_COMMAND_INSTR(0x1B, 0x00),
292 ILI9881C_COMMAND_INSTR(0x1C, 0x00),
293 ILI9881C_COMMAND_INSTR(0x1D, 0x00),
294 ILI9881C_COMMAND_INSTR(0x1E, 0x40),
295 ILI9881C_COMMAND_INSTR(0x1F, 0xC0),
296 ILI9881C_COMMAND_INSTR(0x20, 0x06),
297 ILI9881C_COMMAND_INSTR(0x21, 0x01),
298 ILI9881C_COMMAND_INSTR(0x22, 0x06),
299 ILI9881C_COMMAND_INSTR(0x23, 0x01),
300 ILI9881C_COMMAND_INSTR(0x24, 0x88),
301 ILI9881C_COMMAND_INSTR(0x25, 0x88),
302 ILI9881C_COMMAND_INSTR(0x26, 0x00),
303 ILI9881C_COMMAND_INSTR(0x27, 0x00),
304 ILI9881C_COMMAND_INSTR(0x28, 0x3B),
305 ILI9881C_COMMAND_INSTR(0x29, 0x03),
306 ILI9881C_COMMAND_INSTR(0x2A, 0x00),
307 ILI9881C_COMMAND_INSTR(0x2B, 0x00),
308 ILI9881C_COMMAND_INSTR(0x2C, 0x00),
309 ILI9881C_COMMAND_INSTR(0x2D, 0x00),
310 ILI9881C_COMMAND_INSTR(0x2E, 0x00),
311 ILI9881C_COMMAND_INSTR(0x2F, 0x00),
312 ILI9881C_COMMAND_INSTR(0x30, 0x00),
313 ILI9881C_COMMAND_INSTR(0x31, 0x00),
314 ILI9881C_COMMAND_INSTR(0x32, 0x00),
315 ILI9881C_COMMAND_INSTR(0x33, 0x00),
316 ILI9881C_COMMAND_INSTR(0x34, 0x00), /* GPWR1/2 non overlap time 2.62us */
317 ILI9881C_COMMAND_INSTR(0x35, 0x00),
318 ILI9881C_COMMAND_INSTR(0x36, 0x00),
319 ILI9881C_COMMAND_INSTR(0x37, 0x00),
320 ILI9881C_COMMAND_INSTR(0x38, 0x00),
321 ILI9881C_COMMAND_INSTR(0x39, 0x00),
322 ILI9881C_COMMAND_INSTR(0x3A, 0x00),
323 ILI9881C_COMMAND_INSTR(0x3B, 0x00),
324 ILI9881C_COMMAND_INSTR(0x3C, 0x00),
325 ILI9881C_COMMAND_INSTR(0x3D, 0x00),
326 ILI9881C_COMMAND_INSTR(0x3E, 0x00),
327 ILI9881C_COMMAND_INSTR(0x3F, 0x00),
328 ILI9881C_COMMAND_INSTR(0x40, 0x00),
329 ILI9881C_COMMAND_INSTR(0x41, 0x00),
330 ILI9881C_COMMAND_INSTR(0x42, 0x00),
331 ILI9881C_COMMAND_INSTR(0x43, 0x00),
332 ILI9881C_COMMAND_INSTR(0x44, 0x00),
333 ILI9881C_COMMAND_INSTR(0x50, 0x01),
334 ILI9881C_COMMAND_INSTR(0x51, 0x23),
335 ILI9881C_COMMAND_INSTR(0x52, 0x45),
336 ILI9881C_COMMAND_INSTR(0x53, 0x67),
337 ILI9881C_COMMAND_INSTR(0x54, 0x89),
338 ILI9881C_COMMAND_INSTR(0x55, 0xAB),
339 ILI9881C_COMMAND_INSTR(0x56, 0x01),
340 ILI9881C_COMMAND_INSTR(0x57, 0x23),
341 ILI9881C_COMMAND_INSTR(0x58, 0x45),
342 ILI9881C_COMMAND_INSTR(0x59, 0x67),
343 ILI9881C_COMMAND_INSTR(0x5A, 0x89),
344 ILI9881C_COMMAND_INSTR(0x5B, 0xAB),
345 ILI9881C_COMMAND_INSTR(0x5C, 0xCD),
346 ILI9881C_COMMAND_INSTR(0x5D, 0xEF),
347 ILI9881C_COMMAND_INSTR(0x5E, 0x00),
348 ILI9881C_COMMAND_INSTR(0x5F, 0x01),
349 ILI9881C_COMMAND_INSTR(0x60, 0x01),
350 ILI9881C_COMMAND_INSTR(0x61, 0x06),
351 ILI9881C_COMMAND_INSTR(0x62, 0x06),
352 ILI9881C_COMMAND_INSTR(0x63, 0x07),
353 ILI9881C_COMMAND_INSTR(0x64, 0x07),
354 ILI9881C_COMMAND_INSTR(0x65, 0x00),
355 ILI9881C_COMMAND_INSTR(0x66, 0x00),
356 ILI9881C_COMMAND_INSTR(0x67, 0x02),
357 ILI9881C_COMMAND_INSTR(0x68, 0x02),
358 ILI9881C_COMMAND_INSTR(0x69, 0x05),
359 ILI9881C_COMMAND_INSTR(0x6A, 0x05),
360 ILI9881C_COMMAND_INSTR(0x6B, 0x02),
361 ILI9881C_COMMAND_INSTR(0x6C, 0x0D),
362 ILI9881C_COMMAND_INSTR(0x6D, 0x0D),
363 ILI9881C_COMMAND_INSTR(0x6E, 0x0C),
364 ILI9881C_COMMAND_INSTR(0x6F, 0x0C),
365 ILI9881C_COMMAND_INSTR(0x70, 0x0F),
366 ILI9881C_COMMAND_INSTR(0x71, 0x0F),
367 ILI9881C_COMMAND_INSTR(0x72, 0x0E),
368 ILI9881C_COMMAND_INSTR(0x73, 0x0E),
369 ILI9881C_COMMAND_INSTR(0x74, 0x02),
370 ILI9881C_COMMAND_INSTR(0x75, 0x01),
371 ILI9881C_COMMAND_INSTR(0x76, 0x01),
372 ILI9881C_COMMAND_INSTR(0x77, 0x06),
373 ILI9881C_COMMAND_INSTR(0x78, 0x06),
374 ILI9881C_COMMAND_INSTR(0x79, 0x07),
375 ILI9881C_COMMAND_INSTR(0x7A, 0x07),
376 ILI9881C_COMMAND_INSTR(0x7B, 0x00),
377 ILI9881C_COMMAND_INSTR(0x7C, 0x00),
378 ILI9881C_COMMAND_INSTR(0x7D, 0x02),
379 ILI9881C_COMMAND_INSTR(0x7E, 0x02),
380 ILI9881C_COMMAND_INSTR(0x7F, 0x05),
381 ILI9881C_COMMAND_INSTR(0x80, 0x05),
382 ILI9881C_COMMAND_INSTR(0x81, 0x02),
383 ILI9881C_COMMAND_INSTR(0x82, 0x0D),
384 ILI9881C_COMMAND_INSTR(0x83, 0x0D),
385 ILI9881C_COMMAND_INSTR(0x84, 0x0C),
386 ILI9881C_COMMAND_INSTR(0x85, 0x0C),
387 ILI9881C_COMMAND_INSTR(0x86, 0x0F),
388 ILI9881C_COMMAND_INSTR(0x87, 0x0F),
389 ILI9881C_COMMAND_INSTR(0x88, 0x0E),
390 ILI9881C_COMMAND_INSTR(0x89, 0x0E),
391 ILI9881C_COMMAND_INSTR(0x8A, 0x02),
392 ILI9881C_SWITCH_PAGE_INSTR(4),
393 ILI9881C_COMMAND_INSTR(0x3B, 0xC0), /* ILI4003D sel */
394 ILI9881C_COMMAND_INSTR(0x6C, 0x15), /* Set VCORE voltage = 1.5V */
395 ILI9881C_COMMAND_INSTR(0x6E, 0x2A), /* di_pwr_reg=0 for power mode 2A, VGH clamp 18V */
396 ILI9881C_COMMAND_INSTR(0x6F, 0x33), /* pumping ratio VGH=5x VGL=-3x */
397 ILI9881C_COMMAND_INSTR(0x8D, 0x1B), /* VGL clamp -10V */
398 ILI9881C_COMMAND_INSTR(0x87, 0xBA), /* ESD */
399 ILI9881C_COMMAND_INSTR(0x3A, 0x24), /* POWER SAVING */
400 ILI9881C_COMMAND_INSTR(0x26, 0x76),
401 ILI9881C_COMMAND_INSTR(0xB2, 0xD1),
402 ILI9881C_SWITCH_PAGE_INSTR(1),
403 ILI9881C_COMMAND_INSTR(0x22, 0x0A), /* BGR, SS */
404 ILI9881C_COMMAND_INSTR(0x31, 0x00), /* Zigzag type3 inversion */
405 ILI9881C_COMMAND_INSTR(0x40, 0x53), /* ILI4003D sel */
406 ILI9881C_COMMAND_INSTR(0x43, 0x66),
407 ILI9881C_COMMAND_INSTR(0x53, 0x4C),
408 ILI9881C_COMMAND_INSTR(0x50, 0x87),
409 ILI9881C_COMMAND_INSTR(0x51, 0x82),
410 ILI9881C_COMMAND_INSTR(0x60, 0x15),
411 ILI9881C_COMMAND_INSTR(0x61, 0x01),
412 ILI9881C_COMMAND_INSTR(0x62, 0x0C),
413 ILI9881C_COMMAND_INSTR(0x63, 0x00),
414 ILI9881C_COMMAND_INSTR(0xA0, 0x00),
415 ILI9881C_COMMAND_INSTR(0xA1, 0x13), /* VP251 */
416 ILI9881C_COMMAND_INSTR(0xA2, 0x23), /* VP247 */
417 ILI9881C_COMMAND_INSTR(0xA3, 0x14), /* VP243 */
418 ILI9881C_COMMAND_INSTR(0xA4, 0x16), /* VP239 */
419 ILI9881C_COMMAND_INSTR(0xA5, 0x29), /* VP231 */
420 ILI9881C_COMMAND_INSTR(0xA6, 0x1E), /* VP219 */
421 ILI9881C_COMMAND_INSTR(0xA7, 0x1D), /* VP203 */
422 ILI9881C_COMMAND_INSTR(0xA8, 0x86), /* VP175 */
423 ILI9881C_COMMAND_INSTR(0xA9, 0x1E), /* VP144 */
424 ILI9881C_COMMAND_INSTR(0xAA, 0x29), /* VP111 */
425 ILI9881C_COMMAND_INSTR(0xAB, 0x74), /* VP80 */
426 ILI9881C_COMMAND_INSTR(0xAC, 0x19), /* VP52 */
427 ILI9881C_COMMAND_INSTR(0xAD, 0x17), /* VP36 */
428 ILI9881C_COMMAND_INSTR(0xAE, 0x4B), /* VP24 */
429 ILI9881C_COMMAND_INSTR(0xAF, 0x20), /* VP16 */
430 ILI9881C_COMMAND_INSTR(0xB0, 0x26), /* VP12 */
431 ILI9881C_COMMAND_INSTR(0xB1, 0x4C), /* VP8 */
432 ILI9881C_COMMAND_INSTR(0xB2, 0x5D), /* VP4 */
433 ILI9881C_COMMAND_INSTR(0xB3, 0x3F), /* VP0 */
434 ILI9881C_COMMAND_INSTR(0xC0, 0x00), /* VN255 GAMMA N */
435 ILI9881C_COMMAND_INSTR(0xC1, 0x13), /* VN251 */
436 ILI9881C_COMMAND_INSTR(0xC2, 0x23), /* VN247 */
437 ILI9881C_COMMAND_INSTR(0xC3, 0x14), /* VN243 */
438 ILI9881C_COMMAND_INSTR(0xC4, 0x16), /* VN239 */
439 ILI9881C_COMMAND_INSTR(0xC5, 0x29), /* VN231 */
440 ILI9881C_COMMAND_INSTR(0xC6, 0x1E), /* VN219 */
441 ILI9881C_COMMAND_INSTR(0xC7, 0x1D), /* VN203 */
442 ILI9881C_COMMAND_INSTR(0xC8, 0x86), /* VN175 */
443 ILI9881C_COMMAND_INSTR(0xC9, 0x1E), /* VN144 */
444 ILI9881C_COMMAND_INSTR(0xCA, 0x29), /* VN111 */
445 ILI9881C_COMMAND_INSTR(0xCB, 0x74), /* VN80 */
446 ILI9881C_COMMAND_INSTR(0xCC, 0x19), /* VN52 */
447 ILI9881C_COMMAND_INSTR(0xCD, 0x17), /* VN36 */
448 ILI9881C_COMMAND_INSTR(0xCE, 0x4B), /* VN24 */
449 ILI9881C_COMMAND_INSTR(0xCF, 0x20), /* VN16 */
450 ILI9881C_COMMAND_INSTR(0xD0, 0x26), /* VN12 */
451 ILI9881C_COMMAND_INSTR(0xD1, 0x4C), /* VN8 */
452 ILI9881C_COMMAND_INSTR(0xD2, 0x5D), /* VN4 */
453 ILI9881C_COMMAND_INSTR(0xD3, 0x3F), /* VN0 */
454};
455
255static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel)456static inline struct ili9881c *panel_to_ili9881c(struct drm_panel *panel)
256{457{
257 return container_of(panel, struct ili9881c, panel);458 return container_of(panel, struct ili9881c, panel);
@@ -311,8 +512,8 @@ static int ili9881c_prepare(struct drm_panel *panel) · 53 unmodified lines
311 gpiod_set_value(ctx->reset, 0);512 gpiod_set_value(ctx->reset, 0);
312 msleep(20);513 msleep(20);
313 514
314 for (i = 0; i < ARRAY_SIZE(ili9881c_init); i++) {515 for (i = 0; i < ctx->desc->init_length; i++) {
315 const struct ili9881c_instr *instr = &ili9881c_init[i];516 const struct ili9881c_instr *instr = &ctx->desc->init[i];
316 517
317 if (instr->op == ILI9881C_SWITCH_PAGE)518 if (instr->op == ILI9881C_SWITCH_PAGE)
318 ret = ili9881c_switch_page(ctx, instr->arg.page);519 ret = ili9881c_switch_page(ctx, instr->arg.page);
@@ -368,7 +569,7 @@ static int ili9881c_unprepare(struct drm_panel *panel) · 49 unmodified lines
368 return 0;569 return 0;
369}570}
370 571
371static const struct drm_display_mode bananapi_default_mode = {572static const struct drm_display_mode lhr050h41_default_mode = {
372 .clock = 62000,573 .clock = 62000,
373 574
374 .hdisplay = 720,575 .hdisplay = 720,
@@ -380,6 +581,26 @@ static const struct drm_display_mode bananapi_default_mode = { · 5 unmodified lines
380 .vsync_start = 1280 + 10,581 .vsync_start = 1280 + 10,
381 .vsync_end = 1280 + 10 + 10,582 .vsync_end = 1280 + 10 + 10,
382 .vtotal = 1280 + 10 + 10 + 20,583 .vtotal = 1280 + 10 + 10 + 20,
584
585 .width_mm = 62,
586 .height_mm = 110,
587};
588
589static const struct drm_display_mode k101_im2byl02_default_mode = {
590 .clock = 69700,
591
592 .hdisplay = 800,
593 .hsync_start = 800 + 6,
594 .hsync_end = 800 + 6 + 15,
595 .htotal = 800 + 6 + 15 + 16,
596
597 .vdisplay = 1280,
598 .vsync_start = 1280 + 8,
599 .vsync_end = 1280 + 8 + 48,
600 .vtotal = 1280 + 8 + 48 + 52,
601
602 .width_mm = 135,
603 .height_mm = 217,
383};604};
384 605
385static int ili9881c_get_modes(struct drm_panel *panel,606static int ili9881c_get_modes(struct drm_panel *panel,
@@ -388,12 +609,12 @@ static int ili9881c_get_modes(struct drm_panel *panel, · 2 unmodified lines
388 struct ili9881c *ctx = panel_to_ili9881c(panel);609 struct ili9881c *ctx = panel_to_ili9881c(panel);
389 struct drm_display_mode *mode;610 struct drm_display_mode *mode;
390 611
391 mode = drm_mode_duplicate(connector->dev, &bananapi_default_mode);612 mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
392 if (!mode) {613 if (!mode) {
393 dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",614 dev_err(&ctx->dsi->dev, "failed to add mode %ux%ux@%u\n",
394 bananapi_default_mode.hdisplay,615 ctx->desc->mode->hdisplay,
395 bananapi_default_mode.vdisplay,616 ctx->desc->mode->vdisplay,
396 drm_mode_vrefresh(&bananapi_default_mode));617 drm_mode_vrefresh(ctx->desc->mode));
397 return -ENOMEM;618 return -ENOMEM;
398 }619 }
399 620
@@ -402,8 +623,8 @@ static int ili9881c_get_modes(struct drm_panel *panel, · 2 unmodified lines
402 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;623 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
403 drm_mode_probed_add(connector, mode);624 drm_mode_probed_add(connector, mode);
404 625
405 connector->display_info.width_mm = 62;626 connector->display_info.width_mm = mode->width_mm;
406 connector->display_info.height_mm = 110;627 connector->display_info.height_mm = mode->height_mm;
407 628
408 return 1;629 return 1;
409}630}
@@ -426,6 +647,7 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) · 16 unmodified lines
426 return -ENOMEM;647 return -ENOMEM;
427 mipi_dsi_set_drvdata(dsi, ctx);648 mipi_dsi_set_drvdata(dsi, ctx);
428 ctx->dsi = dsi;649 ctx->dsi = dsi;
650 ctx->desc = of_device_get_match_data(&dsi->dev);
429 651
430 drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs,652 drm_panel_init(&ctx->panel, &dsi->dev, &ili9881c_funcs,
431 DRM_MODE_CONNECTOR_DSI);653 DRM_MODE_CONNECTOR_DSI);
@@ -446,9 +668,7 @@ static int ili9881c_dsi_probe(struct mipi_dsi_device *dsi) · 14 unmodified lines
446 if (ret)668 if (ret)
447 return ret;669 return ret;
448 670
449 ret = drm_panel_add(&ctx->panel);671 drm_panel_add(&ctx->panel);
450 if (ret < 0)
451 return ret;
452 672
453 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;673 dsi->mode_flags = MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
454 dsi->format = MIPI_DSI_FMT_RGB888;674 dsi->format = MIPI_DSI_FMT_RGB888;
@@ -467,8 +687,21 @@ static int ili9881c_dsi_remove(struct mipi_dsi_device *dsi) · 12 unmodified lines
467 return 0;687 return 0;
468}688}
469 689
690static const struct ili9881c_desc lhr050h41_desc = {
691 .init = lhr050h41_init,
692 .init_length = ARRAY_SIZE(lhr050h41_init),
693 .mode = &lhr050h41_default_mode,
694};
695
696static const struct ili9881c_desc k101_im2byl02_desc = {
697 .init = k101_im2byl02_init,
698 .init_length = ARRAY_SIZE(k101_im2byl02_init),
699 .mode = &k101_im2byl02_default_mode,
700};
701
470static const struct of_device_id ili9881c_of_match[] = {702static const struct of_device_id ili9881c_of_match[] = {
471 { .compatible = "bananapi,lhr050h41" },703 { .compatible = "bananapi,lhr050h41", .data = &lhr050h41_desc },
704 { .compatible = "feixin,k101-im2byl02", .data = &k101_im2byl02_desc },
472 { }705 { }
473};706};
474MODULE_DEVICE_TABLE(of, ili9881c_of_match);707MODULE_DEVICE_TABLE(of, ili9881c_of_match);
drivers/gpu/drm/panel/panel-innolux-p079zca.c+12−23
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_mipi_dsi.h>17#include <drm/drm_mipi_dsi.h>
18#include <drm/drm_modes.h>18#include <drm/drm_modes.h>
19#include <drm/drm_panel.h>19#include <drm/drm_panel.h>
20#include <drm/drm_print.h>
21 20
22struct panel_init_cmd {21struct panel_init_cmd {
23 size_t len;22 size_t len;
@@ -85,13 +84,11 @@ static int innolux_panel_unprepare(struct drm_panel *panel) · 61 unmodified lines
85 84
86 err = mipi_dsi_dcs_set_display_off(innolux->link);85 err = mipi_dsi_dcs_set_display_off(innolux->link);
87 if (err < 0)86 if (err < 0)
88 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",87 dev_err(panel->dev, "failed to set display off: %d\n", err);
89 err);
90 88
91 err = mipi_dsi_dcs_enter_sleep_mode(innolux->link);89 err = mipi_dsi_dcs_enter_sleep_mode(innolux->link);
92 if (err < 0) {90 if (err < 0) {
93 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",91 dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
94 err);
95 return err;92 return err;
96 }93 }
97 94
@@ -147,8 +144,7 @@ static int innolux_panel_prepare(struct drm_panel *panel) · 49 unmodified lines
147 err = mipi_dsi_generic_write(innolux->link, cmd->data,144 err = mipi_dsi_generic_write(innolux->link, cmd->data,
148 cmd->len);145 cmd->len);
149 if (err < 0) {146 if (err < 0) {
150 dev_err(panel->dev,147 dev_err(panel->dev, "failed to write command %u\n", i);
151 "failed to write command %u\n", i);
152 goto poweroff;148 goto poweroff;
153 }149 }
154 150
@@ -159,8 +155,7 @@ static int innolux_panel_prepare(struct drm_panel *panel) · 4 unmodified lines
159 */155 */
160 err = mipi_dsi_dcs_nop(innolux->link);156 err = mipi_dsi_dcs_nop(innolux->link);
161 if (err < 0) {157 if (err < 0) {
162 dev_err(panel->dev,158 dev_err(panel->dev, "failed to send DCS nop: %d\n", err);
163 "failed to send DCS nop: %d\n", err);
164 goto poweroff;159 goto poweroff;
165 }160 }
166 }161 }
@@ -168,8 +163,7 @@ static int innolux_panel_prepare(struct drm_panel *panel) · 1 unmodified line
168 163
169 err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);164 err = mipi_dsi_dcs_exit_sleep_mode(innolux->link);
170 if (err < 0) {165 if (err < 0) {
171 DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n",166 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
172 err);
173 goto poweroff;167 goto poweroff;
174 }168 }
175 169
@@ -178,8 +172,7 @@ static int innolux_panel_prepare(struct drm_panel *panel) · 2 unmodified lines
178 172
179 err = mipi_dsi_dcs_set_display_on(innolux->link);173 err = mipi_dsi_dcs_set_display_on(innolux->link);
180 if (err < 0) {174 if (err < 0) {
181 DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n",175 dev_err(panel->dev, "failed to set display on: %d\n", err);
182 err);
183 goto poweroff;176 goto poweroff;
184 }177 }
185 178
@@ -398,8 +391,8 @@ static int innolux_panel_get_modes(struct drm_panel *panel, · 212 unmodified lines
398 391
399 mode = drm_mode_duplicate(connector->dev, m);392 mode = drm_mode_duplicate(connector->dev, m);
400 if (!mode) {393 if (!mode) {
401 DRM_DEV_ERROR(panel->dev, "failed to add mode %ux%ux@%u\n",394 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
402 m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));395 m->hdisplay, m->vdisplay, drm_mode_vrefresh(m));
403 return -ENOMEM;396 return -ENOMEM;
404 }397 }
405 398
@@ -475,9 +468,7 @@ static int innolux_panel_add(struct mipi_dsi_device *dsi, · 69 unmodified lines
475 if (err)468 if (err)
476 return err;469 return err;
477 470
478 err = drm_panel_add(&innolux->base);471 drm_panel_add(&innolux->base);
479 if (err < 0)
480 return err;
481 472
482 mipi_dsi_set_drvdata(dsi, innolux);473 mipi_dsi_set_drvdata(dsi, innolux);
483 innolux->link = dsi;474 innolux->link = dsi;
@@ -514,17 +505,15 @@ static int innolux_panel_remove(struct mipi_dsi_device *dsi) · 30 unmodified lines
514 505
515 err = drm_panel_unprepare(&innolux->base);506 err = drm_panel_unprepare(&innolux->base);
516 if (err < 0)507 if (err < 0)
517 DRM_DEV_ERROR(&dsi->dev, "failed to unprepare panel: %d\n",508 dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
518 err);
519 509
520 err = drm_panel_disable(&innolux->base);510 err = drm_panel_disable(&innolux->base);
521 if (err < 0)511 if (err < 0)
522 DRM_DEV_ERROR(&dsi->dev, "failed to disable panel: %d\n", err);512 dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
523 513
524 err = mipi_dsi_detach(dsi);514 err = mipi_dsi_detach(dsi);
525 if (err < 0)515 if (err < 0)
526 DRM_DEV_ERROR(&dsi->dev, "failed to detach from DSI host: %d\n",516 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
527 err);
528 517
529 innolux_panel_del(innolux);518 innolux_panel_del(innolux);
530 519
drivers/gpu/drm/panel/panel-jdi-lt070me05000.c+2−2
@@ -440,9 +440,9 @@ static int jdi_panel_add(struct jdi_panel *jdi) · 439 unmodified lines
440 drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,440 drm_panel_init(&jdi->base, &jdi->dsi->dev, &jdi_panel_funcs,
441 DRM_MODE_CONNECTOR_DSI);441 DRM_MODE_CONNECTOR_DSI);
442 442
443 ret = drm_panel_add(&jdi->base);443 drm_panel_add(&jdi->base);
444 444
445 return ret;445 return 0;
446}446}
447 447
448static void jdi_panel_del(struct jdi_panel *jdi)448static void jdi_panel_del(struct jdi_panel *jdi)
drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c+15−22
@@ -16,7 +16,6 @@ · 15 unmodified lines
16#include <drm/drm_mipi_dsi.h>16#include <drm/drm_mipi_dsi.h>
17#include <drm/drm_modes.h>17#include <drm/drm_modes.h>
18#include <drm/drm_panel.h>18#include <drm/drm_panel.h>
19#include <drm/drm_print.h>
20 19
21struct kingdisplay_panel {20struct kingdisplay_panel {
22 struct drm_panel base;21 struct drm_panel base;
@@ -191,8 +190,7 @@ static int kingdisplay_panel_disable(struct drm_panel *panel) · 168 unmodified lines
191 190
192 err = mipi_dsi_dcs_set_display_off(kingdisplay->link);191 err = mipi_dsi_dcs_set_display_off(kingdisplay->link);
193 if (err < 0)192 if (err < 0)
194 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",193 dev_err(panel->dev, "failed to set display off: %d\n", err);
195 err);
196 194
197 kingdisplay->enabled = false;195 kingdisplay->enabled = false;
198 196
@@ -209,8 +207,7 @@ static int kingdisplay_panel_unprepare(struct drm_panel *panel) · 10 unmodified lines
209 207
210 err = mipi_dsi_dcs_enter_sleep_mode(kingdisplay->link);208 err = mipi_dsi_dcs_enter_sleep_mode(kingdisplay->link);
211 if (err < 0) {209 if (err < 0) {
212 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",210 dev_err(panel->dev, "failed to enter sleep mode: %d\n", err);
213 err);
214 return err;211 return err;
215 }212 }
216 213
@@ -255,16 +252,14 @@ static int kingdisplay_panel_prepare(struct drm_panel *panel) · 38 unmodified lines
255 err = mipi_dsi_generic_write(kingdisplay->link, &init_code[i],252 err = mipi_dsi_generic_write(kingdisplay->link, &init_code[i],
256 sizeof(struct kingdisplay_panel_cmd));253 sizeof(struct kingdisplay_panel_cmd));
257 if (err < 0) {254 if (err < 0) {
258 DRM_DEV_ERROR(panel->dev, "failed write init cmds: %d\n",255 dev_err(panel->dev, "failed write init cmds: %d\n", err);
259 err);
260 goto poweroff;256 goto poweroff;
261 }257 }
262 }258 }
263 259
264 err = mipi_dsi_dcs_exit_sleep_mode(kingdisplay->link);260 err = mipi_dsi_dcs_exit_sleep_mode(kingdisplay->link);
265 if (err < 0) {261 if (err < 0) {
266 DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n",262 dev_err(panel->dev, "failed to exit sleep mode: %d\n", err);
267 err);
268 goto poweroff;263 goto poweroff;
269 }264 }
270 265
@@ -273,8 +268,7 @@ static int kingdisplay_panel_prepare(struct drm_panel *panel) · 2 unmodified lines
273 268
274 err = mipi_dsi_dcs_set_display_on(kingdisplay->link);269 err = mipi_dsi_dcs_set_display_on(kingdisplay->link);
275 if (err < 0) {270 if (err < 0) {
276 DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n",271 dev_err(panel->dev, "failed to set display on: %d\n", err);
277 err);
278 goto poweroff;272 goto poweroff;
279 }273 }
280 274
@@ -290,8 +284,7 @@ poweroff: · 9 unmodified lines
290 284
291 regulator_err = regulator_disable(kingdisplay->supply);285 regulator_err = regulator_disable(kingdisplay->supply);
292 if (regulator_err)286 if (regulator_err)
293 DRM_DEV_ERROR(panel->dev, "failed to disable regulator: %d\n",287 dev_err(panel->dev, "failed to disable regulator: %d\n", regulator_err);
294 regulator_err);
295 288
296 return err;289 return err;
297}290}
@@ -327,9 +320,9 @@ static int kingdisplay_panel_get_modes(struct drm_panel *panel, · 29 unmodified lines
327 320
328 mode = drm_mode_duplicate(connector->dev, &default_mode);321 mode = drm_mode_duplicate(connector->dev, &default_mode);
329 if (!mode) {322 if (!mode) {
330 DRM_DEV_ERROR(panel->dev, "failed to add mode %ux%ux@%u\n",323 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
331 default_mode.hdisplay, default_mode.vdisplay,324 default_mode.hdisplay, default_mode.vdisplay,
332 drm_mode_vrefresh(&default_mode));325 drm_mode_vrefresh(&default_mode));
333 return -ENOMEM;326 return -ENOMEM;
334 }327 }
335 328
@@ -382,7 +375,9 @@ static int kingdisplay_panel_add(struct kingdisplay_panel *kingdisplay) · 46 unmodified lines
382 if (err)375 if (err)
383 return err;376 return err;
384 377
385 return drm_panel_add(&kingdisplay->base);378 drm_panel_add(&kingdisplay->base);
379
380 return 0;
386}381}
387 382
388static void kingdisplay_panel_del(struct kingdisplay_panel *kingdisplay)383static void kingdisplay_panel_del(struct kingdisplay_panel *kingdisplay)
@@ -421,17 +416,15 @@ static int kingdisplay_panel_remove(struct mipi_dsi_device *dsi) · 32 unmodified lines
421 416
422 err = drm_panel_unprepare(&kingdisplay->base);417 err = drm_panel_unprepare(&kingdisplay->base);
423 if (err < 0)418 if (err < 0)
424 DRM_DEV_ERROR(&dsi->dev, "failed to unprepare panel: %d\n",419 dev_err(&dsi->dev, "failed to unprepare panel: %d\n", err);
425 err);
426 420
427 err = drm_panel_disable(&kingdisplay->base);421 err = drm_panel_disable(&kingdisplay->base);
428 if (err < 0)422 if (err < 0)
429 DRM_DEV_ERROR(&dsi->dev, "failed to disable panel: %d\n", err);423 dev_err(&dsi->dev, "failed to disable panel: %d\n", err);
430 424
431 err = mipi_dsi_detach(dsi);425 err = mipi_dsi_detach(dsi);
432 if (err < 0)426 if (err < 0)
433 DRM_DEV_ERROR(&dsi->dev, "failed to detach from DSI host: %d\n",427 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err);
434 err);
435 428
436 kingdisplay_panel_del(kingdisplay);429 kingdisplay_panel_del(kingdisplay);
437 430
drivers/gpu/drm/panel/panel-leadtek-ltk050h3146w.c+20−38
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_mipi_dsi.h>17#include <drm/drm_mipi_dsi.h>
18#include <drm/drm_modes.h>18#include <drm/drm_modes.h>
19#include <drm/drm_panel.h>19#include <drm/drm_panel.h>
20#include <drm/drm_print.h>
21 20
22struct ltk050h3146w_cmd {21struct ltk050h3146w_cmd {
23 char cmd;22 char cmd;
@@ -314,8 +313,7 @@ static int ltk050h3146w_init_sequence(struct ltk050h3146w *ctx) · 290 unmodified lines
314 313
315 ret = mipi_dsi_dcs_set_tear_on(dsi, 1);314 ret = mipi_dsi_dcs_set_tear_on(dsi, 1);
316 if (ret < 0) {315 if (ret < 0) {
317 DRM_DEV_ERROR(ctx->dev, "failed to set tear on: %d\n",316 dev_err(ctx->dev, "failed to set tear on: %d\n", ret);
318 ret);
319 return ret;317 return ret;
320 }318 }
321 319
@@ -360,8 +358,7 @@ static int ltk050h3146w_a2_write_page(struct ltk050h3146w *ctx, int page, · 38 unmodified lines
360 358
361 ret = ltk050h3146w_a2_select_page(ctx, page);359 ret = ltk050h3146w_a2_select_page(ctx, page);
362 if (ret < 0) {360 if (ret < 0) {
363 DRM_DEV_ERROR(ctx->dev, "failed to select page %d: %d\n",361 dev_err(ctx->dev, "failed to select page %d: %d\n", page, ret);
364 page, ret);
365 return ret;362 return ret;
366 }363 }
367 364
@@ -369,9 +366,7 @@ static int ltk050h3146w_a2_write_page(struct ltk050h3146w *ctx, int page, · 1 unmodified line
369 ret = mipi_dsi_generic_write(dsi, &cmds[i],366 ret = mipi_dsi_generic_write(dsi, &cmds[i],
370 sizeof(struct ltk050h3146w_cmd));367 sizeof(struct ltk050h3146w_cmd));
371 if (ret < 0) {368 if (ret < 0) {
372 DRM_DEV_ERROR(ctx->dev,369 dev_err(ctx->dev, "failed to write page %d init cmds: %d\n", page, ret);
373 "failed to write page %d init cmds: %d\n",
374 page, ret);
375 return ret;370 return ret;
376 }371 }
377 }372 }
@@ -405,15 +400,14 @@ static int ltk050h3146w_a2_init_sequence(struct ltk050h3146w *ctx) · 27 unmodified lines
405 400
406 ret = ltk050h3146w_a2_select_page(ctx, 0);401 ret = ltk050h3146w_a2_select_page(ctx, 0);
407 if (ret < 0) {402 if (ret < 0) {
408 DRM_DEV_ERROR(ctx->dev, "failed to select page 0: %d\n", ret);403 dev_err(ctx->dev, "failed to select page 0: %d\n", ret);
409 return ret;404 return ret;
410 }405 }
411 406
412 /* vendor code called this without param, where there should be one */407 /* vendor code called this without param, where there should be one */
413 ret = mipi_dsi_dcs_set_tear_on(dsi, 0);408 ret = mipi_dsi_dcs_set_tear_on(dsi, 0);
414 if (ret < 0) {409 if (ret < 0) {
415 DRM_DEV_ERROR(ctx->dev, "failed to set tear on: %d\n",410 dev_err(ctx->dev, "failed to set tear on: %d\n", ret);
416 ret);
417 return ret;411 return ret;
418 }412 }
419 413
@@ -452,15 +446,13 @@ static int ltk050h3146w_unprepare(struct drm_panel *panel) · 32 unmodified lines
452 446
453 ret = mipi_dsi_dcs_set_display_off(dsi);447 ret = mipi_dsi_dcs_set_display_off(dsi);
454 if (ret < 0) {448 if (ret < 0) {
455 DRM_DEV_ERROR(ctx->dev, "failed to set display off: %d\n",449 dev_err(ctx->dev, "failed to set display off: %d\n", ret);
456 ret);
457 return ret;450 return ret;
458 }451 }
459 452
460 mipi_dsi_dcs_enter_sleep_mode(dsi);453 mipi_dsi_dcs_enter_sleep_mode(dsi);
461 if (ret < 0) {454 if (ret < 0) {
462 DRM_DEV_ERROR(ctx->dev, "failed to enter sleep mode: %d\n",455 dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret);
463 ret);
464 return ret;456 return ret;
465 }457 }
466 458
@@ -481,17 +473,15 @@ static int ltk050h3146w_prepare(struct drm_panel *panel) · 14 unmodified lines
481 if (ctx->prepared)473 if (ctx->prepared)
482 return 0;474 return 0;
483 475
484 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");476 dev_dbg(ctx->dev, "Resetting the panel\n");
485 ret = regulator_enable(ctx->vci);477 ret = regulator_enable(ctx->vci);
486 if (ret < 0) {478 if (ret < 0) {
487 DRM_DEV_ERROR(ctx->dev,479 dev_err(ctx->dev, "Failed to enable vci supply: %d\n", ret);
488 "Failed to enable vci supply: %d\n", ret);
489 return ret;480 return ret;
490 }481 }
491 ret = regulator_enable(ctx->iovcc);482 ret = regulator_enable(ctx->iovcc);
492 if (ret < 0) {483 if (ret < 0) {
493 DRM_DEV_ERROR(ctx->dev,484 dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
494 "Failed to enable iovcc supply: %d\n", ret);
495 goto disable_vci;485 goto disable_vci;
496 }486 }
497 487
@@ -502,14 +492,13 @@ static int ltk050h3146w_prepare(struct drm_panel *panel) · 4 unmodified lines
502 492
503 ret = ctx->panel_desc->init(ctx);493 ret = ctx->panel_desc->init(ctx);
504 if (ret < 0) {494 if (ret < 0) {
505 DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",495 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
506 ret);
507 goto disable_iovcc;496 goto disable_iovcc;
508 }497 }
509 498
510 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);499 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
511 if (ret < 0) {500 if (ret < 0) {
512 DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);501 dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
513 goto disable_iovcc;502 goto disable_iovcc;
514 }503 }
515 504
@@ -518,7 +507,7 @@ static int ltk050h3146w_prepare(struct drm_panel *panel) · 2 unmodified lines
518 507
519 ret = mipi_dsi_dcs_set_display_on(dsi);508 ret = mipi_dsi_dcs_set_display_on(dsi);
520 if (ret < 0) {509 if (ret < 0) {
521 DRM_DEV_ERROR(ctx->dev, "Failed to set display on: %d\n", ret);510 dev_err(ctx->dev, "Failed to set display on: %d\n", ret);
522 goto disable_iovcc;511 goto disable_iovcc;
523 }512 }
524 513
@@ -577,7 +566,7 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) · 52 unmodified lines
577 566
578 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);567 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
579 if (IS_ERR(ctx->reset_gpio)) {568 if (IS_ERR(ctx->reset_gpio)) {
580 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");569 dev_err(dev, "cannot get reset gpio\n");
581 return PTR_ERR(ctx->reset_gpio);570 return PTR_ERR(ctx->reset_gpio);
582 }571 }
583 572
@@ -585,9 +574,7 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
585 if (IS_ERR(ctx->vci)) {574 if (IS_ERR(ctx->vci)) {
586 ret = PTR_ERR(ctx->vci);575 ret = PTR_ERR(ctx->vci);
587 if (ret != -EPROBE_DEFER)576 if (ret != -EPROBE_DEFER)
588 DRM_DEV_ERROR(dev,577 dev_err(dev, "Failed to request vci regulator: %d\n", ret);
589 "Failed to request vci regulator: %d\n",
590 ret);
591 return ret;578 return ret;
592 }579 }
593 580
@@ -595,9 +582,7 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
595 if (IS_ERR(ctx->iovcc)) {582 if (IS_ERR(ctx->iovcc)) {
596 ret = PTR_ERR(ctx->iovcc);583 ret = PTR_ERR(ctx->iovcc);
597 if (ret != -EPROBE_DEFER)584 if (ret != -EPROBE_DEFER)
598 DRM_DEV_ERROR(dev,585 dev_err(dev, "Failed to request iovcc regulator: %d\n", ret);
599 "Failed to request iovcc regulator: %d\n",
600 ret);
601 return ret;586 return ret;
602 }587 }
603 588
@@ -621,7 +606,7 @@ static int ltk050h3146w_probe(struct mipi_dsi_device *dsi) · 17 unmodified lines
621 606
622 ret = mipi_dsi_attach(dsi);607 ret = mipi_dsi_attach(dsi);
623 if (ret < 0) {608 if (ret < 0) {
624 DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret);609 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
625 drm_panel_remove(&ctx->panel);610 drm_panel_remove(&ctx->panel);
626 return ret;611 return ret;
627 }612 }
@@ -636,13 +621,11 @@ static void ltk050h3146w_shutdown(struct mipi_dsi_device *dsi) · 8 unmodified lines
636 621
637 ret = drm_panel_unprepare(&ctx->panel);622 ret = drm_panel_unprepare(&ctx->panel);
638 if (ret < 0)623 if (ret < 0)
639 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",624 dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
640 ret);
641 625
642 ret = drm_panel_disable(&ctx->panel);626 ret = drm_panel_disable(&ctx->panel);
643 if (ret < 0)627 if (ret < 0)
644 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",628 dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
645 ret);
646}629}
647 630
648static int ltk050h3146w_remove(struct mipi_dsi_device *dsi)631static int ltk050h3146w_remove(struct mipi_dsi_device *dsi)
@@ -654,8 +637,7 @@ static int ltk050h3146w_remove(struct mipi_dsi_device *dsi) · 5 unmodified lines
654 637
655 ret = mipi_dsi_detach(dsi);638 ret = mipi_dsi_detach(dsi);
656 if (ret < 0)639 if (ret < 0)
657 DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",640 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
658 ret);
659 641
660 drm_panel_remove(&ctx->panel);642 drm_panel_remove(&ctx->panel);
661 643
drivers/gpu/drm/panel/panel-leadtek-ltk500hd1829.c+17−32
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include <drm/drm_mipi_dsi.h>20#include <drm/drm_mipi_dsi.h>
21#include <drm/drm_modes.h>21#include <drm/drm_modes.h>
22#include <drm/drm_panel.h>22#include <drm/drm_panel.h>
23#include <drm/drm_print.h>
24 23
25struct ltk500hd1829 {24struct ltk500hd1829 {
26 struct device *dev;25 struct device *dev;
@@ -278,13 +277,11 @@ static int ltk500hd1829_unprepare(struct drm_panel *panel) · 251 unmodified lines
278 277
279 ret = mipi_dsi_dcs_set_display_off(dsi);278 ret = mipi_dsi_dcs_set_display_off(dsi);
280 if (ret < 0)279 if (ret < 0)
281 DRM_DEV_ERROR(panel->dev, "failed to set display off: %d\n",280 dev_err(panel->dev, "failed to set display off: %d\n", ret);
282 ret);
283 281
284 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);282 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
285 if (ret < 0) {283 if (ret < 0) {
286 DRM_DEV_ERROR(panel->dev, "failed to enter sleep mode: %d\n",284 dev_err(panel->dev, "failed to enter sleep mode: %d\n", ret);
287 ret);
288 }285 }
289 286
290 /* 120ms to enter sleep mode */287 /* 120ms to enter sleep mode */
@@ -310,14 +307,12 @@ static int ltk500hd1829_prepare(struct drm_panel *panel) · 19 unmodified lines
310 307
311 ret = regulator_enable(ctx->vcc);308 ret = regulator_enable(ctx->vcc);
312 if (ret < 0) {309 if (ret < 0) {
313 DRM_DEV_ERROR(ctx->dev,310 dev_err(ctx->dev, "Failed to enable vci supply: %d\n", ret);
314 "Failed to enable vci supply: %d\n", ret);
315 return ret;311 return ret;
316 }312 }
317 ret = regulator_enable(ctx->iovcc);313 ret = regulator_enable(ctx->iovcc);
318 if (ret < 0) {314 if (ret < 0) {
319 DRM_DEV_ERROR(ctx->dev,315 dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
320 "Failed to enable iovcc supply: %d\n", ret);
321 goto disable_vcc;316 goto disable_vcc;
322 }317 }
323 318
@@ -333,16 +328,14 @@ static int ltk500hd1829_prepare(struct drm_panel *panel) · 9 unmodified lines
333 ret = mipi_dsi_generic_write(dsi, &init_code[i],328 ret = mipi_dsi_generic_write(dsi, &init_code[i],
334 sizeof(struct ltk500hd1829_cmd));329 sizeof(struct ltk500hd1829_cmd));
335 if (ret < 0) {330 if (ret < 0) {
336 DRM_DEV_ERROR(panel->dev,331 dev_err(panel->dev, "failed to write init cmds: %d\n", ret);
337 "failed to write init cmds: %d\n", ret);
338 goto disable_iovcc;332 goto disable_iovcc;
339 }333 }
340 }334 }
341 335
342 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);336 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
343 if (ret < 0) {337 if (ret < 0) {
344 DRM_DEV_ERROR(panel->dev, "failed to exit sleep mode: %d\n",338 dev_err(panel->dev, "failed to exit sleep mode: %d\n", ret);
345 ret);
346 goto disable_iovcc;339 goto disable_iovcc;
347 }340 }
348 341
@@ -351,8 +344,7 @@ static int ltk500hd1829_prepare(struct drm_panel *panel) · 2 unmodified lines
351 344
352 ret = mipi_dsi_dcs_set_display_on(dsi);345 ret = mipi_dsi_dcs_set_display_on(dsi);
353 if (ret < 0) {346 if (ret < 0) {
354 DRM_DEV_ERROR(panel->dev, "failed to set display on: %d\n",347 dev_err(panel->dev, "failed to set display on: %d\n", ret);
355 ret);
356 goto disable_iovcc;348 goto disable_iovcc;
357 }349 }
358 350
@@ -389,9 +381,9 @@ static int ltk500hd1829_get_modes(struct drm_panel *panel, · 30 unmodified lines
389 381
390 mode = drm_mode_duplicate(connector->dev, &default_mode);382 mode = drm_mode_duplicate(connector->dev, &default_mode);
391 if (!mode) {383 if (!mode) {
392 DRM_DEV_ERROR(ctx->dev, "failed to add mode %ux%ux@%u\n",384 dev_err(ctx->dev, "failed to add mode %ux%u@%u\n",
393 default_mode.hdisplay, default_mode.vdisplay,385 default_mode.hdisplay, default_mode.vdisplay,
394 drm_mode_vrefresh(&default_mode));386 drm_mode_vrefresh(&default_mode));
395 return -ENOMEM;387 return -ENOMEM;
396 }388 }
397 389
@@ -423,7 +415,7 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) · 25 unmodified lines
423 415
424 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);416 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
425 if (IS_ERR(ctx->reset_gpio)) {417 if (IS_ERR(ctx->reset_gpio)) {
426 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");418 dev_err(dev, "cannot get reset gpio\n");
427 return PTR_ERR(ctx->reset_gpio);419 return PTR_ERR(ctx->reset_gpio);
428 }420 }
429 421
@@ -431,9 +423,7 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
431 if (IS_ERR(ctx->vcc)) {423 if (IS_ERR(ctx->vcc)) {
432 ret = PTR_ERR(ctx->vcc);424 ret = PTR_ERR(ctx->vcc);
433 if (ret != -EPROBE_DEFER)425 if (ret != -EPROBE_DEFER)
434 DRM_DEV_ERROR(dev,426 dev_err(dev, "Failed to request vcc regulator: %d\n", ret);
435 "Failed to request vcc regulator: %d\n",
436 ret);
437 return ret;427 return ret;
438 }428 }
439 429
@@ -441,9 +431,7 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
441 if (IS_ERR(ctx->iovcc)) {431 if (IS_ERR(ctx->iovcc)) {
442 ret = PTR_ERR(ctx->iovcc);432 ret = PTR_ERR(ctx->iovcc);
443 if (ret != -EPROBE_DEFER)433 if (ret != -EPROBE_DEFER)
444 DRM_DEV_ERROR(dev,434 dev_err(dev, "Failed to request iovcc regulator: %d\n", ret);
445 "Failed to request iovcc regulator: %d\n",
446 ret);
447 return ret;435 return ret;
448 }436 }
449 437
@@ -467,7 +455,7 @@ static int ltk500hd1829_probe(struct mipi_dsi_device *dsi) · 17 unmodified lines
467 455
468 ret = mipi_dsi_attach(dsi);456 ret = mipi_dsi_attach(dsi);
469 if (ret < 0) {457 if (ret < 0) {
470 DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret);458 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
471 drm_panel_remove(&ctx->panel);459 drm_panel_remove(&ctx->panel);
472 return ret;460 return ret;
473 }461 }
@@ -482,13 +470,11 @@ static void ltk500hd1829_shutdown(struct mipi_dsi_device *dsi) · 8 unmodified lines
482 470
483 ret = drm_panel_unprepare(&ctx->panel);471 ret = drm_panel_unprepare(&ctx->panel);
484 if (ret < 0)472 if (ret < 0)
485 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",473 dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
486 ret);
487 474
488 ret = drm_panel_disable(&ctx->panel);475 ret = drm_panel_disable(&ctx->panel);
489 if (ret < 0)476 if (ret < 0)
490 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",477 dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
491 ret);
492}478}
493 479
494static int ltk500hd1829_remove(struct mipi_dsi_device *dsi)480static int ltk500hd1829_remove(struct mipi_dsi_device *dsi)
@@ -500,8 +486,7 @@ static int ltk500hd1829_remove(struct mipi_dsi_device *dsi) · 5 unmodified lines
500 486
501 ret = mipi_dsi_detach(dsi);487 ret = mipi_dsi_detach(dsi);
502 if (ret < 0)488 if (ret < 0)
503 DRM_DEV_ERROR(&dsi->dev, "failed to detach from DSI host: %d\n",489 dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
504 ret);
505 490
506 drm_panel_remove(&ctx->panel);491 drm_panel_remove(&ctx->panel);
507 492
drivers/gpu/drm/panel/panel-lg-lb035q02.c+3−1
@@ -198,7 +198,9 @@ static int lb035q02_probe(struct spi_device *spi) · 197 unmodified lines
198 drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs,198 drm_panel_init(&lcd->panel, &lcd->spi->dev, &lb035q02_funcs,
199 DRM_MODE_CONNECTOR_DPI);199 DRM_MODE_CONNECTOR_DPI);
200 200
201 return drm_panel_add(&lcd->panel);201 drm_panel_add(&lcd->panel);
202
203 return 0;
202}204}
203 205
204static int lb035q02_remove(struct spi_device *spi)206static int lb035q02_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-lg-lg4573.c+3−1
@@ -261,7 +261,9 @@ static int lg4573_probe(struct spi_device *spi) · 260 unmodified lines
261 drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs,261 drm_panel_init(&ctx->panel, &spi->dev, &lg4573_drm_funcs,
262 DRM_MODE_CONNECTOR_DPI);262 DRM_MODE_CONNECTOR_DPI);
263 263
264 return drm_panel_add(&ctx->panel);264 drm_panel_add(&ctx->panel);
265
266 return 0;
265}267}
266 268
267static int lg4573_remove(struct spi_device *spi)269static int lg4573_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-lvds.c+10−3
@@ -37,6 +37,8 @@ struct panel_lvds { · 36 unmodified lines
37 37
38 struct gpio_desc *enable_gpio;38 struct gpio_desc *enable_gpio;
39 struct gpio_desc *reset_gpio;39 struct gpio_desc *reset_gpio;
40
41 enum drm_panel_orientation orientation;
40};42};
41 43
42static inline struct panel_lvds *to_panel_lvds(struct drm_panel *panel)44static inline struct panel_lvds *to_panel_lvds(struct drm_panel *panel)
@@ -99,6 +101,7 @@ static int panel_lvds_get_modes(struct drm_panel *panel, · 56 unmodified lines
99 connector->display_info.bus_flags = lvds->data_mirror101 connector->display_info.bus_flags = lvds->data_mirror
100 ? DRM_BUS_FLAG_DATA_LSB_TO_MSB102 ? DRM_BUS_FLAG_DATA_LSB_TO_MSB
101 : DRM_BUS_FLAG_DATA_MSB_TO_LSB;103 : DRM_BUS_FLAG_DATA_MSB_TO_LSB;
104 drm_connector_set_panel_orientation(connector, lvds->orientation);
102 105
103 return 1;106 return 1;
104}107}
@@ -116,6 +119,12 @@ static int panel_lvds_parse_dt(struct panel_lvds *lvds) · 11 unmodified lines
116 const char *mapping;119 const char *mapping;
117 int ret;120 int ret;
118 121
122 ret = of_drm_get_panel_orientation(np, &lvds->orientation);
123 if (ret < 0) {
124 dev_err(lvds->dev, "%pOF: failed to get orientation %d\n", np, ret);
125 return ret;
126 }
127
119 ret = of_get_display_timing(np, "panel-timing", &timing);128 ret = of_get_display_timing(np, "panel-timing", &timing);
120 if (ret < 0) {129 if (ret < 0) {
121 dev_err(lvds->dev, "%pOF: problems parsing panel-timing (%d)\n",130 dev_err(lvds->dev, "%pOF: problems parsing panel-timing (%d)\n",
@@ -227,9 +236,7 @@ static int panel_lvds_probe(struct platform_device *pdev) · 105 unmodified lines
227 if (ret)236 if (ret)
228 return ret;237 return ret;
229 238
230 ret = drm_panel_add(&lvds->panel);239 drm_panel_add(&lvds->panel);
231 if (ret < 0)
232 return ret;
233 240
234 dev_set_drvdata(lvds->dev, lvds);241 dev_set_drvdata(lvds->dev, lvds);
235 return 0;242 return 0;
drivers/gpu/drm/panel/panel-mantix-mlaf057we51.c+328−0
@@ -0,0 +1,328 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Mantix MLAF057WE51 5.7" MIPI-DSI panel driver
4 *
5 * Copyright (C) Purism SPC 2020
6 */
7
8#include <linux/backlight.h>
9#include <linux/delay.h>
10#include <linux/gpio/consumer.h>
11#include <linux/module.h>
12#include <linux/regulator/consumer.h>
13
14#include <video/mipi_display.h>
15
16#include <drm/drm_mipi_dsi.h>
17#include <drm/drm_modes.h>
18#include <drm/drm_panel.h>
19
20#define DRV_NAME "panel-mantix-mlaf057we51"
21
22/* Manufacturer specific Commands send via DSI */
23#define MANTIX_CMD_OTP_STOP_RELOAD_MIPI 0x41
24#define MANTIX_CMD_INT_CANCEL 0x4C
25
26struct mantix {
27 struct device *dev;
28 struct drm_panel panel;
29 struct gpio_desc *reset_gpio;
30
31 struct regulator *avdd;
32 struct regulator *avee;
33 struct regulator *vddi;
34};
35
36static inline struct mantix *panel_to_mantix(struct drm_panel *panel)
37{
38 return container_of(panel, struct mantix, panel);
39}
40
41#define dsi_generic_write_seq(dsi, seq...) do { \
42 static const u8 d[] = { seq }; \
43 int ret; \
44 ret = mipi_dsi_generic_write(dsi, d, ARRAY_SIZE(d)); \
45 if (ret < 0) \
46 return ret; \
47 } while (0)
48
49static int mantix_init_sequence(struct mantix *ctx)
50{
51 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
52 struct device *dev = ctx->dev;
53
54 /*
55 * Init sequence was supplied by the panel vendor.
56 */
57 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A);
58
59 dsi_generic_write_seq(dsi, MANTIX_CMD_INT_CANCEL, 0x03);
60 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x03);
61 dsi_generic_write_seq(dsi, 0x80, 0xA9, 0x00);
62
63 dsi_generic_write_seq(dsi, MANTIX_CMD_OTP_STOP_RELOAD_MIPI, 0x5A, 0x09);
64 dsi_generic_write_seq(dsi, 0x80, 0x64, 0x00, 0x64, 0x00, 0x00);
65 msleep(20);
66
67 dev_dbg(dev, "Panel init sequence done\n");
68 return 0;
69}
70
71static int mantix_enable(struct drm_panel *panel)
72{
73 struct mantix *ctx = panel_to_mantix(panel);
74 struct device *dev = ctx->dev;
75 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
76 int ret;
77
78 ret = mantix_init_sequence(ctx);
79 if (ret < 0) {
80 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
81 return ret;
82 }
83
84 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
85 if (ret < 0) {
86 dev_err(dev, "Failed to exit sleep mode\n");
87 return ret;
88 }
89 msleep(20);
90
91 ret = mipi_dsi_dcs_set_display_on(dsi);
92 if (ret)
93 return ret;
94 usleep_range(10000, 12000);
95
96 ret = mipi_dsi_turn_on_peripheral(dsi);
97 if (ret < 0) {
98 dev_err(dev, "Failed to turn on peripheral\n");
99 return ret;
100 }
101
102 return 0;
103}
104
105static int mantix_disable(struct drm_panel *panel)
106{
107 struct mantix *ctx = panel_to_mantix(panel);
108 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
109 int ret;
110
111 ret = mipi_dsi_dcs_set_display_off(dsi);
112 if (ret < 0)
113 dev_err(ctx->dev, "Failed to turn off the display: %d\n", ret);
114
115 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
116 if (ret < 0)
117 dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret);
118
119
120 return 0;
121}
122
123static int mantix_unprepare(struct drm_panel *panel)
124{
125 struct mantix *ctx = panel_to_mantix(panel);
126
127 regulator_disable(ctx->avee);
128 regulator_disable(ctx->avdd);
129 /* T11 */
130 usleep_range(5000, 6000);
131 regulator_disable(ctx->vddi);
132 /* T14 */
133 msleep(50);
134
135 return 0;
136}
137
138static int mantix_prepare(struct drm_panel *panel)
139{
140 struct mantix *ctx = panel_to_mantix(panel);
141 int ret;
142
143 /* Focaltech FT8006P, section 7.3.1 and 7.3.4 */
144 dev_dbg(ctx->dev, "Resetting the panel\n");
145 ret = regulator_enable(ctx->vddi);
146 if (ret < 0) {
147 dev_err(ctx->dev, "Failed to enable vddi supply: %d\n", ret);
148 return ret;
149 }
150
151 /* T1 + T2 */
152 usleep_range(8000, 10000);
153
154 ret = regulator_enable(ctx->avdd);
155 if (ret < 0) {
156 dev_err(ctx->dev, "Failed to enable avdd supply: %d\n", ret);
157 return ret;
158 }
159
160 /* T2d */
161 usleep_range(3500, 4000);
162 ret = regulator_enable(ctx->avee);
163 if (ret < 0) {
164 dev_err(ctx->dev, "Failed to enable avee supply: %d\n", ret);
165 return ret;
166 }
167
168 /* T3+T5 */
169 usleep_range(10000, 12000);
170
171 gpiod_set_value_cansleep(ctx->reset_gpio, 1);
172 usleep_range(5150, 7000);
173
174 gpiod_set_value_cansleep(ctx->reset_gpio, 0);
175
176 /* T6 */
177 msleep(50);
178
179 return 0;
180}
181
182static const struct drm_display_mode default_mode = {
183 .hdisplay = 720,
184 .hsync_start = 720 + 45,
185 .hsync_end = 720 + 45 + 14,
186 .htotal = 720 + 45 + 14 + 25,
187 .vdisplay = 1440,
188 .vsync_start = 1440 + 130,
189 .vsync_end = 1440 + 130 + 8,
190 .vtotal = 1440 + 130 + 8 + 106,
191 .clock = 85298,
192 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
193 .width_mm = 65,
194 .height_mm = 130,
195};
196
197static int mantix_get_modes(struct drm_panel *panel,
198 struct drm_connector *connector)
199{
200 struct mantix *ctx = panel_to_mantix(panel);
201 struct drm_display_mode *mode;
202
203 mode = drm_mode_duplicate(connector->dev, &default_mode);
204 if (!mode) {
205 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
206 default_mode.hdisplay, default_mode.vdisplay,
207 drm_mode_vrefresh(mode));
208 return -ENOMEM;
209 }
210
211 drm_mode_set_name(mode);
212
213 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
214 connector->display_info.width_mm = mode->width_mm;
215 connector->display_info.height_mm = mode->height_mm;
216 drm_mode_probed_add(connector, mode);
217
218 return 1;
219}
220
221static const struct drm_panel_funcs mantix_drm_funcs = {
222 .disable = mantix_disable,
223 .unprepare = mantix_unprepare,
224 .prepare = mantix_prepare,
225 .enable = mantix_enable,
226 .get_modes = mantix_get_modes,
227};
228
229static int mantix_probe(struct mipi_dsi_device *dsi)
230{
231 struct device *dev = &dsi->dev;
232 struct mantix *ctx;
233 int ret;
234
235 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
236 if (!ctx)
237 return -ENOMEM;
238
239 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
240 if (IS_ERR(ctx->reset_gpio)) {
241 dev_err(dev, "cannot get reset gpio\n");
242 return PTR_ERR(ctx->reset_gpio);
243 }
244
245 mipi_dsi_set_drvdata(dsi, ctx);
246 ctx->dev = dev;
247
248 dsi->lanes = 4;
249 dsi->format = MIPI_DSI_FMT_RGB888;
250 dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
251 MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
252
253 ctx->avdd = devm_regulator_get(dev, "avdd");
254 if (IS_ERR(ctx->avdd))
255 return dev_err_probe(dev, PTR_ERR(ctx->avdd), "Failed to request avdd regulator\n");
256
257 ctx->avee = devm_regulator_get(dev, "avee");
258 if (IS_ERR(ctx->avee))
259 return dev_err_probe(dev, PTR_ERR(ctx->avee), "Failed to request avee regulator\n");
260
261 ctx->vddi = devm_regulator_get(dev, "vddi");
262 if (IS_ERR(ctx->vddi))
263 return dev_err_probe(dev, PTR_ERR(ctx->vddi), "Failed to request vddi regulator\n");
264
265 drm_panel_init(&ctx->panel, dev, &mantix_drm_funcs,
266 DRM_MODE_CONNECTOR_DSI);
267
268 ret = drm_panel_of_backlight(&ctx->panel);
269 if (ret)
270 return ret;
271
272 drm_panel_add(&ctx->panel);
273
274 ret = mipi_dsi_attach(dsi);
275 if (ret < 0) {
276 dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret);
277 drm_panel_remove(&ctx->panel);
278 return ret;
279 }
280
281 dev_info(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
282 default_mode.hdisplay, default_mode.vdisplay,
283 drm_mode_vrefresh(&default_mode),
284 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
285
286 return 0;
287}
288
289static void mantix_shutdown(struct mipi_dsi_device *dsi)
290{
291 struct mantix *ctx = mipi_dsi_get_drvdata(dsi);
292
293 drm_panel_unprepare(&ctx->panel);
294 drm_panel_disable(&ctx->panel);
295}
296
297static int mantix_remove(struct mipi_dsi_device *dsi)
298{
299 struct mantix *ctx = mipi_dsi_get_drvdata(dsi);
300
301 mantix_shutdown(dsi);
302
303 mipi_dsi_detach(dsi);
304 drm_panel_remove(&ctx->panel);
305
306 return 0;
307}
308
309static const struct of_device_id mantix_of_match[] = {
310 { .compatible = "mantix,mlaf057we51-x" },
311 { /* sentinel */ }
312};
313MODULE_DEVICE_TABLE(of, mantix_of_match);
314
315static struct mipi_dsi_driver mantix_driver = {
316 .probe = mantix_probe,
317 .remove = mantix_remove,
318 .shutdown = mantix_shutdown,
319 .driver = {
320 .name = DRV_NAME,
321 .of_match_table = mantix_of_match,
322 },
323};
324module_mipi_dsi_driver(mantix_driver);
325
326MODULE_AUTHOR("Guido Günther <agx@sigxcpu.org>");
327MODULE_DESCRIPTION("DRM driver for Mantix MLAF057WE51-X MIPI DSI panel");
328MODULE_LICENSE("GPL v2");
drivers/gpu/drm/panel/panel-nec-nl8048hl11.c+3−1
@@ -207,7 +207,9 @@ static int nl8048_probe(struct spi_device *spi) · 206 unmodified lines
207 drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs,207 drm_panel_init(&lcd->panel, &lcd->spi->dev, &nl8048_funcs,
208 DRM_MODE_CONNECTOR_DPI);208 DRM_MODE_CONNECTOR_DPI);
209 209
210 return drm_panel_add(&lcd->panel);210 drm_panel_add(&lcd->panel);
211
212 return 0;
211}213}
212 214
213static int nl8048_remove(struct spi_device *spi)215static int nl8048_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-novatek-nt35510.c+31−29
@@ -35,7 +35,6 @@ · 34 unmodified lines
35#include <drm/drm_mipi_dsi.h>35#include <drm/drm_mipi_dsi.h>
36#include <drm/drm_modes.h>36#include <drm/drm_modes.h>
37#include <drm/drm_panel.h>37#include <drm/drm_panel.h>
38#include <drm/drm_print.h>
39 38
40#define MCS_CMD_MAUCCTR 0xF0 /* Manufacturer command enable */39#define MCS_CMD_MAUCCTR 0xF0 /* Manufacturer command enable */
41#define MCS_CMD_READ_ID1 0xDA40#define MCS_CMD_READ_ID1 0xDA
@@ -376,6 +375,10 @@ struct nt35510 { · 334 unmodified lines
376};375};
377 376
378/* Manufacturer command has strictly this byte sequence */377/* Manufacturer command has strictly this byte sequence */
378static const u8 nt35510_mauc_mtp_read_param[] = { 0xAA, 0x55, 0x25, 0x01 };
379static const u8 nt35510_mauc_mtp_read_setting[] = { 0x01, 0x02, 0x00, 0x20,
380 0x33, 0x13, 0x00, 0x40,
381 0x00, 0x00, 0x23, 0x02 };
379static const u8 nt35510_mauc_select_page_0[] = { 0x55, 0xAA, 0x52, 0x08, 0x00 };382static const u8 nt35510_mauc_select_page_0[] = { 0x55, 0xAA, 0x52, 0x08, 0x00 };
380static const u8 nt35510_mauc_select_page_1[] = { 0x55, 0xAA, 0x52, 0x08, 0x01 };383static const u8 nt35510_mauc_select_page_1[] = { 0x55, 0xAA, 0x52, 0x08, 0x01 };
381static const u8 nt35510_vgh_on[] = { 0x01 };384static const u8 nt35510_vgh_on[] = { 0x01 };
@@ -400,9 +403,7 @@ static int nt35510_send_long(struct nt35510 *nt, struct mipi_dsi_device *dsi, · 18 unmodified lines
400 chunk = 15;403 chunk = 15;
401 ret = mipi_dsi_dcs_write(dsi, cmd, seqp, chunk);404 ret = mipi_dsi_dcs_write(dsi, cmd, seqp, chunk);
402 if (ret < 0) {405 if (ret < 0) {
403 DRM_DEV_ERROR(nt->dev,406 dev_err(nt->dev, "error sending DCS command seq cmd %02x\n", cmd);
404 "error sending DCS command seq cmd %02x\n",
405 cmd);
406 return ret;407 return ret;
407 }408 }
408 cmdwritten += chunk;409 cmdwritten += chunk;
@@ -414,16 +415,13 @@ static int nt35510_send_long(struct nt35510 *nt, struct mipi_dsi_device *dsi, · 5 unmodified lines
414 chunk = 15;415 chunk = 15;
415 ret = mipi_dsi_generic_write(dsi, seqp, chunk);416 ret = mipi_dsi_generic_write(dsi, seqp, chunk);
416 if (ret < 0) {417 if (ret < 0) {
417 DRM_DEV_ERROR(nt->dev,418 dev_err(nt->dev, "error sending generic write seq %02x\n", cmd);
418 "error sending generic write seq %02x\n",
419 cmd);
420 return ret;419 return ret;
421 }420 }
422 cmdwritten += chunk;421 cmdwritten += chunk;
423 seqp += chunk;422 seqp += chunk;
424 }423 }
425 DRM_DEV_DEBUG(nt->dev, "sent command %02x %02x bytes\n",424 dev_dbg(nt->dev, "sent command %02x %02x bytes\n", cmd, cmdlen);
426 cmd, cmdlen);
427 return 0;425 return 0;
428}426}
429 427
@@ -435,17 +433,17 @@ static int nt35510_read_id(struct nt35510 *nt) · 5 unmodified lines
435 433
436 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID1, &id1, 1);434 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID1, &id1, 1);
437 if (ret < 0) {435 if (ret < 0) {
438 DRM_DEV_ERROR(nt->dev, "could not read MTP ID1\n");436 dev_err(nt->dev, "could not read MTP ID1\n");
439 return ret;437 return ret;
440 }438 }
441 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID2, &id2, 1);439 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID2, &id2, 1);
442 if (ret < 0) {440 if (ret < 0) {
443 DRM_DEV_ERROR(nt->dev, "could not read MTP ID2\n");441 dev_err(nt->dev, "could not read MTP ID2\n");
444 return ret;442 return ret;
445 }443 }
446 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID3, &id3, 1);444 ret = mipi_dsi_dcs_read(dsi, MCS_CMD_READ_ID3, &id3, 1);
447 if (ret < 0) {445 if (ret < 0) {
448 DRM_DEV_ERROR(nt->dev, "could not read MTP ID3\n");446 dev_err(nt->dev, "could not read MTP ID3\n");
449 return ret;447 return ret;
450 }448 }
451 449
@@ -454,9 +452,7 @@ static int nt35510_read_id(struct nt35510 *nt) · 2 unmodified lines
454 * ID (e.g. Hydis 0x55), driver ID (e.g. NT35510 0xc0) and452 * ID (e.g. Hydis 0x55), driver ID (e.g. NT35510 0xc0) and
455 * version.453 * version.
456 */454 */
457 DRM_DEV_INFO(nt->dev,455 dev_info(nt->dev, "MTP ID manufacturer: %02x version: %02x driver: %02x\n", id1, id2, id3);
458 "MTP ID manufacturer: %02x version: %02x driver: %02x\n",
459 id1, id2, id3);
460 456
461 return 0;457 return 0;
462}458}
@@ -657,7 +653,7 @@ static int nt35510_set_brightness(struct backlight_device *bl) · 194 unmodified lines
657 u8 brightness = bl->props.brightness;653 u8 brightness = bl->props.brightness;
658 int ret;654 int ret;
659 655
660 DRM_DEV_DEBUG(nt->dev, "set brightness %d\n", brightness);656 dev_dbg(nt->dev, "set brightness %d\n", brightness);
661 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,657 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
662 &brightness,658 &brightness,
663 sizeof(brightness));659 sizeof(brightness));
@@ -698,6 +694,18 @@ static int nt35510_power_on(struct nt35510 *nt) · 34 unmodified lines
698 usleep_range(120000, 140000);694 usleep_range(120000, 140000);
699 }695 }
700 696
697 ret = nt35510_send_long(nt, dsi, MCS_CMD_MTP_READ_PARAM,
698 ARRAY_SIZE(nt35510_mauc_mtp_read_param),
699 nt35510_mauc_mtp_read_param);
700 if (ret)
701 return ret;
702
703 ret = nt35510_send_long(nt, dsi, MCS_CMD_MTP_READ_SETTING,
704 ARRAY_SIZE(nt35510_mauc_mtp_read_setting),
705 nt35510_mauc_mtp_read_setting);
706 if (ret)
707 return ret;
708
701 ret = nt35510_read_id(nt);709 ret = nt35510_read_id(nt);
702 if (ret)710 if (ret)
703 return ret;711 return ret;
@@ -780,8 +788,7 @@ static int nt35510_unprepare(struct drm_panel *panel) · 76 unmodified lines
780 788
781 ret = mipi_dsi_dcs_set_display_off(dsi);789 ret = mipi_dsi_dcs_set_display_off(dsi);
782 if (ret) {790 if (ret) {
783 DRM_DEV_ERROR(nt->dev, "failed to turn display off (%d)\n",791 dev_err(nt->dev, "failed to turn display off (%d)\n", ret);
784 ret);
785 return ret;792 return ret;
786 }793 }
787 usleep_range(10000, 20000);794 usleep_range(10000, 20000);
@@ -789,8 +796,7 @@ static int nt35510_unprepare(struct drm_panel *panel) · 1 unmodified line
789 /* Enter sleep mode */796 /* Enter sleep mode */
790 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);797 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
791 if (ret) {798 if (ret) {
792 DRM_DEV_ERROR(nt->dev, "failed to enter sleep mode (%d)\n",799 dev_err(nt->dev, "failed to enter sleep mode (%d)\n", ret);
793 ret);
794 return ret;800 return ret;
795 }801 }
796 802
@@ -817,8 +823,7 @@ static int nt35510_prepare(struct drm_panel *panel) · 20 unmodified lines
817 /* Exit sleep mode */823 /* Exit sleep mode */
818 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);824 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
819 if (ret) {825 if (ret) {
820 DRM_DEV_ERROR(nt->dev, "failed to exit sleep mode (%d)\n",826 dev_err(nt->dev, "failed to exit sleep mode (%d)\n", ret);
821 ret);
822 return ret;827 return ret;
823 }828 }
824 /* Up to 120 ms */829 /* Up to 120 ms */
@@ -826,8 +831,7 @@ static int nt35510_prepare(struct drm_panel *panel) · 1 unmodified line
826 831
827 ret = mipi_dsi_dcs_set_display_on(dsi);832 ret = mipi_dsi_dcs_set_display_on(dsi);
828 if (ret) {833 if (ret) {
829 DRM_DEV_ERROR(nt->dev, "failed to turn display on (%d)\n",834 dev_err(nt->dev, "failed to turn display on (%d)\n", ret);
830 ret);
831 return ret;835 return ret;
832 }836 }
833 /* Some 10 ms */837 /* Some 10 ms */
@@ -848,7 +852,7 @@ static int nt35510_get_modes(struct drm_panel *panel, · 14 unmodified lines
848 info->height_mm = nt->conf->height_mm;852 info->height_mm = nt->conf->height_mm;
849 mode = drm_mode_duplicate(connector->dev, &nt->conf->mode);853 mode = drm_mode_duplicate(connector->dev, &nt->conf->mode);
850 if (!mode) {854 if (!mode) {
851 DRM_ERROR("bad mode or failed to add mode\n");855 dev_err(panel->dev, "bad mode or failed to add mode\n");
852 return -EINVAL;856 return -EINVAL;
853 }857 }
854 drm_mode_set_name(mode);858 drm_mode_set_name(mode);
@@ -947,7 +951,7 @@ static int nt35510_probe(struct mipi_dsi_device *dsi) · 92 unmodified lines
947 bl = devm_backlight_device_register(dev, "nt35510", dev, nt,951 bl = devm_backlight_device_register(dev, "nt35510", dev, nt,
948 &nt35510_bl_ops, NULL);952 &nt35510_bl_ops, NULL);
949 if (IS_ERR(bl)) {953 if (IS_ERR(bl)) {
950 DRM_DEV_ERROR(dev, "failed to register backlight device\n");954 dev_err(dev, "failed to register backlight device\n");
951 return PTR_ERR(bl);955 return PTR_ERR(bl);
952 }956 }
953 bl->props.max_brightness = 255;957 bl->props.max_brightness = 255;
@@ -956,9 +960,7 @@ static int nt35510_probe(struct mipi_dsi_device *dsi) · 2 unmodified lines
956 nt->panel.backlight = bl;960 nt->panel.backlight = bl;
957 }961 }
958 962
959 ret = drm_panel_add(&nt->panel);963 drm_panel_add(&nt->panel);
960 if (ret < 0)
961 return ret;
962 964
963 ret = mipi_dsi_attach(dsi);965 ret = mipi_dsi_attach(dsi);
964 if (ret < 0)966 if (ret < 0)
drivers/gpu/drm/panel/panel-novatek-nt39016.c+16−30
@@ -6,7 +6,6 @@ · 5 unmodified lines
6 * Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>6 * Copyright (C) 2019, Paul Cercueil <paul@crapouillou.net>
7 */7 */
8 8
9#include <linux/backlight.h>
10#include <linux/delay.h>9#include <linux/delay.h>
11#include <linux/device.h>10#include <linux/device.h>
12#include <linux/gpio/consumer.h>11#include <linux/gpio/consumer.h>
@@ -57,14 +56,11 @@ struct nt39016_panel_info { · 44 unmodified lines
57 56
58struct nt39016 {57struct nt39016 {
59 struct drm_panel drm_panel;58 struct drm_panel drm_panel;
60 struct device *dev;
61 struct regmap *map;59 struct regmap *map;
62 struct regulator *supply;60 struct regulator *supply;
63 const struct nt39016_panel_info *panel_info;61 const struct nt39016_panel_info *panel_info;
64 62
65 struct gpio_desc *reset_gpio;63 struct gpio_desc *reset_gpio;
66
67 struct backlight_device *backlight;
68};64};
69 65
70static inline struct nt39016 *to_nt39016(struct drm_panel *panel)66static inline struct nt39016 *to_nt39016(struct drm_panel *panel)
@@ -127,7 +123,7 @@ static int nt39016_prepare(struct drm_panel *drm_panel) · 56 unmodified lines
127 123
128 err = regulator_enable(panel->supply);124 err = regulator_enable(panel->supply);
129 if (err) {125 if (err) {
130 dev_err(panel->dev, "Failed to enable power supply: %d", err);126 dev_err(drm_panel->dev, "Failed to enable power supply: %d\n", err);
131 return err;127 return err;
132 }128 }
133 129
@@ -146,7 +142,7 @@ static int nt39016_prepare(struct drm_panel *drm_panel) · 12 unmodified lines
146 err = regmap_multi_reg_write(panel->map, nt39016_panel_regs,142 err = regmap_multi_reg_write(panel->map, nt39016_panel_regs,
147 ARRAY_SIZE(nt39016_panel_regs));143 ARRAY_SIZE(nt39016_panel_regs));
148 if (err) {144 if (err) {
149 dev_err(panel->dev, "Failed to init registers: %d", err);145 dev_err(drm_panel->dev, "Failed to init registers: %d\n", err);
150 goto err_disable_regulator;146 goto err_disable_regulator;
151 }147 }
152 148
@@ -176,18 +172,16 @@ static int nt39016_enable(struct drm_panel *drm_panel) · 23 unmodified lines
176 ret = regmap_write(panel->map, NT39016_REG_SYSTEM,172 ret = regmap_write(panel->map, NT39016_REG_SYSTEM,
177 NT39016_SYSTEM_RESET_N | NT39016_SYSTEM_STANDBY);173 NT39016_SYSTEM_RESET_N | NT39016_SYSTEM_STANDBY);
178 if (ret) {174 if (ret) {
179 dev_err(panel->dev, "Unable to enable panel: %d", ret);175 dev_err(drm_panel->dev, "Unable to enable panel: %d\n", ret);
180 return ret;176 return ret;
181 }177 }
182 178
183 if (panel->backlight) {179 if (drm_panel->backlight) {
184 /* Wait for the picture to be ready before enabling backlight */180 /* Wait for the picture to be ready before enabling backlight */
185 msleep(150);181 msleep(150);
186
187 ret = backlight_enable(panel->backlight);
188 }182 }
189 183
190 return ret;184 return 0;
191}185}
192 186
193static int nt39016_disable(struct drm_panel *drm_panel)187static int nt39016_disable(struct drm_panel *drm_panel)
@@ -195,12 +189,10 @@ static int nt39016_disable(struct drm_panel *drm_panel) · 1 unmodified line
195 struct nt39016 *panel = to_nt39016(drm_panel);189 struct nt39016 *panel = to_nt39016(drm_panel);
196 int err;190 int err;
197 191
198 backlight_disable(panel->backlight);
199
200 err = regmap_write(panel->map, NT39016_REG_SYSTEM,192 err = regmap_write(panel->map, NT39016_REG_SYSTEM,
201 NT39016_SYSTEM_RESET_N);193 NT39016_SYSTEM_RESET_N);
202 if (err) {194 if (err) {
203 dev_err(panel->dev, "Unable to disable panel: %d", err);195 dev_err(drm_panel->dev, "Unable to disable panel: %d\n", err);
204 return err;196 return err;
205 }197 }
206 198
@@ -259,7 +251,6 @@ static int nt39016_probe(struct spi_device *spi) · 52 unmodified lines
259 if (!panel)251 if (!panel)
260 return -ENOMEM;252 return -ENOMEM;
261 253
262 panel->dev = dev;
263 spi_set_drvdata(spi, panel);254 spi_set_drvdata(spi, panel);
264 255
265 panel->panel_info = of_device_get_match_data(dev);256 panel->panel_info = of_device_get_match_data(dev);
@@ -268,13 +259,13 @@ static int nt39016_probe(struct spi_device *spi) · 2 unmodified lines
268 259
269 panel->supply = devm_regulator_get(dev, "power");260 panel->supply = devm_regulator_get(dev, "power");
270 if (IS_ERR(panel->supply)) {261 if (IS_ERR(panel->supply)) {
271 dev_err(dev, "Failed to get power supply");262 dev_err(dev, "Failed to get power supply\n");
272 return PTR_ERR(panel->supply);263 return PTR_ERR(panel->supply);
273 }264 }
274 265
275 panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);266 panel->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
276 if (IS_ERR(panel->reset_gpio)) {267 if (IS_ERR(panel->reset_gpio)) {
277 dev_err(dev, "Failed to get reset GPIO");268 dev_err(dev, "Failed to get reset GPIO\n");
278 return PTR_ERR(panel->reset_gpio);269 return PTR_ERR(panel->reset_gpio);
279 }270 }
280 271
@@ -282,33 +273,28 @@ static int nt39016_probe(struct spi_device *spi) · 1 unmodified line
282 spi->mode = SPI_MODE_3 | SPI_3WIRE;273 spi->mode = SPI_MODE_3 | SPI_3WIRE;
283 err = spi_setup(spi);274 err = spi_setup(spi);
284 if (err) {275 if (err) {
285 dev_err(dev, "Failed to setup SPI");276 dev_err(dev, "Failed to setup SPI\n");
286 return err;277 return err;
287 }278 }
288 279
289 panel->map = devm_regmap_init_spi(spi, &nt39016_regmap_config);280 panel->map = devm_regmap_init_spi(spi, &nt39016_regmap_config);
290 if (IS_ERR(panel->map)) {281 if (IS_ERR(panel->map)) {
291 dev_err(dev, "Failed to init regmap");282 dev_err(dev, "Failed to init regmap\n");
292 return PTR_ERR(panel->map);283 return PTR_ERR(panel->map);
293 }284 }
294 285
295 panel->backlight = devm_of_find_backlight(dev);
296 if (IS_ERR(panel->backlight)) {
297 err = PTR_ERR(panel->backlight);
298 if (err != -EPROBE_DEFER)
299 dev_err(dev, "Failed to get backlight handle");
300 return err;
301 }
302
303 drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs,286 drm_panel_init(&panel->drm_panel, dev, &nt39016_funcs,
304 DRM_MODE_CONNECTOR_DPI);287 DRM_MODE_CONNECTOR_DPI);
305 288
306 err = drm_panel_add(&panel->drm_panel);289 err = drm_panel_of_backlight(&panel->drm_panel);
307 if (err < 0) {290 if (err) {
308 dev_err(dev, "Failed to register panel");291 if (err != -EPROBE_DEFER)
292 dev_err(dev, "Failed to get backlight handle\n");
309 return err;293 return err;
310 }294 }
311 295
296 drm_panel_add(&panel->drm_panel);
297
312 return 0;298 return 0;
313}299}
314 300
drivers/gpu/drm/panel/panel-olimex-lcd-olinuxino.c+3−1
@@ -283,7 +283,9 @@ static int lcd_olinuxino_probe(struct i2c_client *client, · 282 unmodified lines
283 if (ret)283 if (ret)
284 return ret;284 return ret;
285 285
286 return drm_panel_add(&lcd->panel);286 drm_panel_add(&lcd->panel);
287
288 return 0;
287}289}
288 290
289static int lcd_olinuxino_remove(struct i2c_client *client)291static int lcd_olinuxino_remove(struct i2c_client *client)
drivers/gpu/drm/panel/panel-orisetech-otm8009a.c+6−7
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_mipi_dsi.h>17#include <drm/drm_mipi_dsi.h>
18#include <drm/drm_modes.h>18#include <drm/drm_modes.h>
19#include <drm/drm_panel.h>19#include <drm/drm_panel.h>
20#include <drm/drm_print.h>
21 20
22#define OTM8009A_BACKLIGHT_DEFAULT 24021#define OTM8009A_BACKLIGHT_DEFAULT 240
23#define OTM8009A_BACKLIGHT_MAX 25522#define OTM8009A_BACKLIGHT_MAX 255
@@ -97,7 +96,7 @@ static void otm8009a_dcs_write_buf(struct otm8009a *ctx, const void *data, · 73 unmodified lines
97 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);96 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
98 97
99 if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0)98 if (mipi_dsi_dcs_write_buffer(dsi, data, len) < 0)
100 DRM_WARN("mipi dsi dcs write buffer failed\n");99 dev_warn(ctx->dev, "mipi dsi dcs write buffer failed\n");
101}100}
102 101
103static void otm8009a_dcs_write_buf_hs(struct otm8009a *ctx, const void *data,102static void otm8009a_dcs_write_buf_hs(struct otm8009a *ctx, const void *data,
@@ -313,7 +312,7 @@ static int otm8009a_prepare(struct drm_panel *panel) · 209 unmodified lines
313 312
314 ret = regulator_enable(ctx->supply);313 ret = regulator_enable(ctx->supply);
315 if (ret < 0) {314 if (ret < 0) {
316 DRM_ERROR("failed to enable supply: %d\n", ret);315 dev_err(panel->dev, "failed to enable supply: %d\n", ret);
317 return ret;316 return ret;
318 }317 }
319 318
@@ -355,9 +354,9 @@ static int otm8009a_get_modes(struct drm_panel *panel, · 35 unmodified lines
355 354
356 mode = drm_mode_duplicate(connector->dev, &default_mode);355 mode = drm_mode_duplicate(connector->dev, &default_mode);
357 if (!mode) {356 if (!mode) {
358 DRM_ERROR("failed to add mode %ux%ux@%u\n",357 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
359 default_mode.hdisplay, default_mode.vdisplay,358 default_mode.hdisplay, default_mode.vdisplay,
360 drm_mode_vrefresh(&default_mode));359 drm_mode_vrefresh(&default_mode));
361 return -ENOMEM;360 return -ENOMEM;
362 }361 }
363 362
@@ -390,7 +389,7 @@ static int otm8009a_backlight_update_status(struct backlight_device *bd) · 26 unmodified lines
390 u8 data[2];389 u8 data[2];
391 390
392 if (!ctx->prepared) {391 if (!ctx->prepared) {
393 DRM_DEBUG("lcd not ready yet for setting its backlight!\n");392 dev_dbg(&bd->dev, "lcd not ready yet for setting its backlight!\n");
394 return -ENXIO;393 return -ENXIO;
395 }394 }
396 395
drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c+3−1
@@ -164,7 +164,9 @@ static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587) · 163 unmodified lines
164 if (ret)164 if (ret)
165 return ret;165 return ret;
166 166
167 return drm_panel_add(&osd101t2587->base);167 drm_panel_add(&osd101t2587->base);
168
169 return 0;
168}170}
169 171
170static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi)172static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi)
drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c+3−1
@@ -206,7 +206,9 @@ static int wuxga_nt_panel_add(struct wuxga_nt_panel *wuxga_nt) · 205 unmodified lines
206 if (ret)206 if (ret)
207 return ret;207 return ret;
208 208
209 return drm_panel_add(&wuxga_nt->base);209 drm_panel_add(&wuxga_nt->base);
210
211 return 0;
210}212}
211 213
212static void wuxga_nt_panel_del(struct wuxga_nt_panel *wuxga_nt)214static void wuxga_nt_panel_del(struct wuxga_nt_panel *wuxga_nt)
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c+2−4
@@ -361,7 +361,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, · 360 unmodified lines
361 struct rpi_touchscreen *ts;361 struct rpi_touchscreen *ts;
362 struct device_node *endpoint, *dsi_host_node;362 struct device_node *endpoint, *dsi_host_node;
363 struct mipi_dsi_host *host;363 struct mipi_dsi_host *host;
364 int ret, ver;364 int ver;
365 struct mipi_dsi_device_info info = {365 struct mipi_dsi_device_info info = {
366 .type = RPI_DSI_DRIVER_NAME,366 .type = RPI_DSI_DRIVER_NAME,
367 .channel = 0,367 .channel = 0,
@@ -429,9 +429,7 @@ static int rpi_touchscreen_probe(struct i2c_client *i2c, · 61 unmodified lines
429 /* This appears last, as it's what will unblock the DSI host429 /* This appears last, as it's what will unblock the DSI host
430 * driver's component bind function.430 * driver's component bind function.
431 */431 */
432 ret = drm_panel_add(&ts->base);432 drm_panel_add(&ts->base);
433 if (ret)
434 return ret;
435 433
436 return 0;434 return 0;
437 435
drivers/gpu/drm/panel/panel-raydium-rm67191.c+16−21
@@ -19,7 +19,6 @@ · 18 unmodified lines
19#include <drm/drm_crtc.h>19#include <drm/drm_crtc.h>
20#include <drm/drm_mipi_dsi.h>20#include <drm/drm_mipi_dsi.h>
21#include <drm/drm_panel.h>21#include <drm/drm_panel.h>
22#include <drm/drm_print.h>
23 22
24/* Panel specific color-format bits */23/* Panel specific color-format bits */
25#define COL_FMT_16BPP 0x5524#define COL_FMT_16BPP 0x55
@@ -329,7 +328,7 @@ static int rad_panel_enable(struct drm_panel *panel) · 303 unmodified lines
329 328
330 ret = rad_panel_push_cmd_list(dsi);329 ret = rad_panel_push_cmd_list(dsi);
331 if (ret < 0) {330 if (ret < 0) {
332 DRM_DEV_ERROR(dev, "Failed to send MCS (%d)\n", ret);331 dev_err(dev, "Failed to send MCS (%d)\n", ret);
333 goto fail;332 goto fail;
334 }333 }
335 334
@@ -341,7 +340,7 @@ static int rad_panel_enable(struct drm_panel *panel) · 5 unmodified lines
341 /* Software reset */340 /* Software reset */
342 ret = mipi_dsi_dcs_soft_reset(dsi);341 ret = mipi_dsi_dcs_soft_reset(dsi);
343 if (ret < 0) {342 if (ret < 0) {
344 DRM_DEV_ERROR(dev, "Failed to do Software Reset (%d)\n", ret);343 dev_err(dev, "Failed to do Software Reset (%d)\n", ret);
345 goto fail;344 goto fail;
346 }345 }
347 346
@@ -350,33 +349,32 @@ static int rad_panel_enable(struct drm_panel *panel) · 2 unmodified lines
350 /* Set DSI mode */349 /* Set DSI mode */
351 ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2);350 ret = mipi_dsi_generic_write(dsi, (u8[]){ 0xC2, 0x0B }, 2);
352 if (ret < 0) {351 if (ret < 0) {
353 DRM_DEV_ERROR(dev, "Failed to set DSI mode (%d)\n", ret);352 dev_err(dev, "Failed to set DSI mode (%d)\n", ret);
354 goto fail;353 goto fail;
355 }354 }
356 /* Set tear ON */355 /* Set tear ON */
357 ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);356 ret = mipi_dsi_dcs_set_tear_on(dsi, MIPI_DSI_DCS_TEAR_MODE_VBLANK);
358 if (ret < 0) {357 if (ret < 0) {
359 DRM_DEV_ERROR(dev, "Failed to set tear ON (%d)\n", ret);358 dev_err(dev, "Failed to set tear ON (%d)\n", ret);
360 goto fail;359 goto fail;
361 }360 }
362 /* Set tear scanline */361 /* Set tear scanline */
363 ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380);362 ret = mipi_dsi_dcs_set_tear_scanline(dsi, 0x380);
364 if (ret < 0) {363 if (ret < 0) {
365 DRM_DEV_ERROR(dev, "Failed to set tear scanline (%d)\n", ret);364 dev_err(dev, "Failed to set tear scanline (%d)\n", ret);
366 goto fail;365 goto fail;
367 }366 }
368 /* Set pixel format */367 /* Set pixel format */
369 ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format);368 ret = mipi_dsi_dcs_set_pixel_format(dsi, color_format);
370 DRM_DEV_DEBUG_DRIVER(dev, "Interface color format set to 0x%x\n",369 dev_dbg(dev, "Interface color format set to 0x%x\n", color_format);
371 color_format);
372 if (ret < 0) {370 if (ret < 0) {
373 DRM_DEV_ERROR(dev, "Failed to set pixel format (%d)\n", ret);371 dev_err(dev, "Failed to set pixel format (%d)\n", ret);
374 goto fail;372 goto fail;
375 }373 }
376 /* Exit sleep mode */374 /* Exit sleep mode */
377 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);375 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
378 if (ret < 0) {376 if (ret < 0) {
379 DRM_DEV_ERROR(dev, "Failed to exit sleep mode (%d)\n", ret);377 dev_err(dev, "Failed to exit sleep mode (%d)\n", ret);
380 goto fail;378 goto fail;
381 }379 }
382 380
@@ -384,7 +382,7 @@ static int rad_panel_enable(struct drm_panel *panel) · 1 unmodified line
384 382
385 ret = mipi_dsi_dcs_set_display_on(dsi);383 ret = mipi_dsi_dcs_set_display_on(dsi);
386 if (ret < 0) {384 if (ret < 0) {
387 DRM_DEV_ERROR(dev, "Failed to set display ON (%d)\n", ret);385 dev_err(dev, "Failed to set display ON (%d)\n", ret);
388 goto fail;386 goto fail;
389 }387 }
390 388
@@ -418,7 +416,7 @@ static int rad_panel_disable(struct drm_panel *panel) · 27 unmodified lines
418 416
419 ret = mipi_dsi_dcs_set_display_off(dsi);417 ret = mipi_dsi_dcs_set_display_off(dsi);
420 if (ret < 0) {418 if (ret < 0) {
421 DRM_DEV_ERROR(dev, "Failed to set display OFF (%d)\n", ret);419 dev_err(dev, "Failed to set display OFF (%d)\n", ret);
422 return ret;420 return ret;
423 }421 }
424 422
@@ -426,7 +424,7 @@ static int rad_panel_disable(struct drm_panel *panel) · 1 unmodified line
426 424
427 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);425 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
428 if (ret < 0) {426 if (ret < 0) {
429 DRM_DEV_ERROR(dev, "Failed to enter sleep mode (%d)\n", ret);427 dev_err(dev, "Failed to enter sleep mode (%d)\n", ret);
430 return ret;428 return ret;
431 }429 }
432 430
@@ -442,9 +440,9 @@ static int rad_panel_get_modes(struct drm_panel *panel, · 9 unmodified lines
442 440
443 mode = drm_mode_duplicate(connector->dev, &default_mode);441 mode = drm_mode_duplicate(connector->dev, &default_mode);
444 if (!mode) {442 if (!mode) {
445 DRM_DEV_ERROR(panel->dev, "failed to add mode %ux%ux@%u\n",443 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
446 default_mode.hdisplay, default_mode.vdisplay,444 default_mode.hdisplay, default_mode.vdisplay,
447 drm_mode_vrefresh(&default_mode));445 drm_mode_vrefresh(&default_mode));
448 return -ENOMEM;446 return -ENOMEM;
449 }447 }
450 448
@@ -609,9 +607,7 @@ static int rad_panel_probe(struct mipi_dsi_device *dsi) · 158 unmodified lines
609 DRM_MODE_CONNECTOR_DSI);607 DRM_MODE_CONNECTOR_DSI);
610 dev_set_drvdata(dev, panel);608 dev_set_drvdata(dev, panel);
611 609
612 ret = drm_panel_add(&panel->panel);610 drm_panel_add(&panel->panel);
613 if (ret)
614 return ret;
615 611
616 ret = mipi_dsi_attach(dsi);612 ret = mipi_dsi_attach(dsi);
617 if (ret)613 if (ret)
@@ -628,8 +624,7 @@ static int rad_panel_remove(struct mipi_dsi_device *dsi) · 10 unmodified lines
628 624
629 ret = mipi_dsi_detach(dsi);625 ret = mipi_dsi_detach(dsi);
630 if (ret)626 if (ret)
631 DRM_DEV_ERROR(dev, "Failed to detach from host (%d)\n",627 dev_err(dev, "Failed to detach from host (%d)\n", ret);
632 ret);
633 628
634 drm_panel_remove(&rad->panel);629 drm_panel_remove(&rad->panel);
635 630
drivers/gpu/drm/panel/panel-raydium-rm68200.c+8−10
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_mipi_dsi.h>17#include <drm/drm_mipi_dsi.h>
18#include <drm/drm_modes.h>18#include <drm/drm_modes.h>
19#include <drm/drm_panel.h>19#include <drm/drm_panel.h>
20#include <drm/drm_print.h>
21 20
22/*** Manufacturer Command Set ***/21/*** Manufacturer Command Set ***/
23#define MCS_CMD_MODE_SW 0xFE /* CMD Mode Switch */22#define MCS_CMD_MODE_SW 0xFE /* CMD Mode Switch */
@@ -110,8 +109,7 @@ static void rm68200_dcs_write_buf(struct rm68200 *ctx, const void *data, · 86 unmodified lines
110 109
111 err = mipi_dsi_dcs_write_buffer(dsi, data, len);110 err = mipi_dsi_dcs_write_buffer(dsi, data, len);
112 if (err < 0)111 if (err < 0)
113 DRM_ERROR_RATELIMITED("MIPI DSI DCS write buffer failed: %d\n",112 dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write buffer failed: %d\n", err);
114 err);
115}113}
116 114
117static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)115static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value)
@@ -121,7 +119,7 @@ static void rm68200_dcs_write_cmd(struct rm68200 *ctx, u8 cmd, u8 value) · 3 unmodified lines
121 119
122 err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);120 err = mipi_dsi_dcs_write(dsi, cmd, &value, 1);
123 if (err < 0)121 if (err < 0)
124 DRM_ERROR_RATELIMITED("MIPI DSI DCS write failed: %d\n", err);122 dev_err_ratelimited(ctx->dev, "MIPI DSI DCS write failed: %d\n", err);
125}123}
126 124
127#define dcs_write_seq(ctx, seq...) \125#define dcs_write_seq(ctx, seq...) \
@@ -256,11 +254,11 @@ static int rm68200_unprepare(struct drm_panel *panel) · 128 unmodified lines
256 254
257 ret = mipi_dsi_dcs_set_display_off(dsi);255 ret = mipi_dsi_dcs_set_display_off(dsi);
258 if (ret)256 if (ret)
259 DRM_WARN("failed to set display off: %d\n", ret);257 dev_warn(panel->dev, "failed to set display off: %d\n", ret);
260 258
261 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);259 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
262 if (ret)260 if (ret)
263 DRM_WARN("failed to enter sleep mode: %d\n", ret);261 dev_warn(panel->dev, "failed to enter sleep mode: %d\n", ret);
264 262
265 msleep(120);263 msleep(120);
266 264
@@ -287,7 +285,7 @@ static int rm68200_prepare(struct drm_panel *panel) · 20 unmodified lines
287 285
288 ret = regulator_enable(ctx->supply);286 ret = regulator_enable(ctx->supply);
289 if (ret < 0) {287 if (ret < 0) {
290 DRM_ERROR("failed to enable supply: %d\n", ret);288 dev_err(ctx->dev, "failed to enable supply: %d\n", ret);
291 return ret;289 return ret;
292 }290 }
293 291
@@ -336,9 +334,9 @@ static int rm68200_get_modes(struct drm_panel *panel, · 42 unmodified lines
336 334
337 mode = drm_mode_duplicate(connector->dev, &default_mode);335 mode = drm_mode_duplicate(connector->dev, &default_mode);
338 if (!mode) {336 if (!mode) {
339 DRM_ERROR("failed to add mode %ux%ux@%u\n",337 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
340 default_mode.hdisplay, default_mode.vdisplay,338 default_mode.hdisplay, default_mode.vdisplay,
341 drm_mode_vrefresh(&default_mode));339 drm_mode_vrefresh(&default_mode));
342 return -ENOMEM;340 return -ENOMEM;
343 }341 }
344 342
drivers/gpu/drm/panel/panel-ronbo-rb070d30.c+8−12
@@ -23,7 +23,6 @@ · 22 unmodified lines
23#include <drm/drm_mipi_dsi.h>23#include <drm/drm_mipi_dsi.h>
24#include <drm/drm_modes.h>24#include <drm/drm_modes.h>
25#include <drm/drm_panel.h>25#include <drm/drm_panel.h>
26#include <drm/drm_print.h>
27 26
28struct rb070d30_panel {27struct rb070d30_panel {
29 struct drm_panel panel;28 struct drm_panel panel;
@@ -50,7 +49,7 @@ static int rb070d30_panel_prepare(struct drm_panel *panel) · 20 unmodified lines
50 49
51 ret = regulator_enable(ctx->supply);50 ret = regulator_enable(ctx->supply);
52 if (ret < 0) {51 if (ret < 0) {
53 DRM_DEV_ERROR(&ctx->dsi->dev, "Failed to enable supply: %d\n", ret);52 dev_err(&ctx->dsi->dev, "Failed to enable supply: %d\n", ret);
54 return ret;53 return ret;
55 }54 }
56 55
@@ -117,9 +116,8 @@ static int rb070d30_panel_get_modes(struct drm_panel *panel, · 60 unmodified lines
117 116
118 mode = drm_mode_duplicate(connector->dev, &default_mode);117 mode = drm_mode_duplicate(connector->dev, &default_mode);
119 if (!mode) {118 if (!mode) {
120 DRM_DEV_ERROR(&ctx->dsi->dev,119 dev_err(&ctx->dsi->dev, "Failed to add mode " DRM_MODE_FMT "\n",
121 "Failed to add mode " DRM_MODE_FMT "\n",120 DRM_MODE_ARG(&default_mode));
122 DRM_MODE_ARG(&default_mode));
123 return -EINVAL;121 return -EINVAL;
124 }122 }
125 123
@@ -166,13 +164,13 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) · 40 unmodified lines
166 164
167 ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);165 ctx->gpios.reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
168 if (IS_ERR(ctx->gpios.reset)) {166 if (IS_ERR(ctx->gpios.reset)) {
169 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our reset GPIO\n");167 dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
170 return PTR_ERR(ctx->gpios.reset);168 return PTR_ERR(ctx->gpios.reset);
171 }169 }
172 170
173 ctx->gpios.power = devm_gpiod_get(&dsi->dev, "power", GPIOD_OUT_LOW);171 ctx->gpios.power = devm_gpiod_get(&dsi->dev, "power", GPIOD_OUT_LOW);
174 if (IS_ERR(ctx->gpios.power)) {172 if (IS_ERR(ctx->gpios.power)) {
175 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our power GPIO\n");173 dev_err(&dsi->dev, "Couldn't get our power GPIO\n");
176 return PTR_ERR(ctx->gpios.power);174 return PTR_ERR(ctx->gpios.power);
177 }175 }
178 176
@@ -182,7 +180,7 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) · 3 unmodified lines
182 */180 */
183 ctx->gpios.updn = devm_gpiod_get(&dsi->dev, "updn", GPIOD_OUT_LOW);181 ctx->gpios.updn = devm_gpiod_get(&dsi->dev, "updn", GPIOD_OUT_LOW);
184 if (IS_ERR(ctx->gpios.updn)) {182 if (IS_ERR(ctx->gpios.updn)) {
185 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our updn GPIO\n");183 dev_err(&dsi->dev, "Couldn't get our updn GPIO\n");
186 return PTR_ERR(ctx->gpios.updn);184 return PTR_ERR(ctx->gpios.updn);
187 }185 }
188 186
@@ -192,7 +190,7 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) · 3 unmodified lines
192 */190 */
193 ctx->gpios.shlr = devm_gpiod_get(&dsi->dev, "shlr", GPIOD_OUT_LOW);191 ctx->gpios.shlr = devm_gpiod_get(&dsi->dev, "shlr", GPIOD_OUT_LOW);
194 if (IS_ERR(ctx->gpios.shlr)) {192 if (IS_ERR(ctx->gpios.shlr)) {
195 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our shlr GPIO\n");193 dev_err(&dsi->dev, "Couldn't get our shlr GPIO\n");
196 return PTR_ERR(ctx->gpios.shlr);194 return PTR_ERR(ctx->gpios.shlr);
197 }195 }
198 196
@@ -200,9 +198,7 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
200 if (ret)198 if (ret)
201 return ret;199 return ret;
202 200
203 ret = drm_panel_add(&ctx->panel);201 drm_panel_add(&ctx->panel);
204 if (ret < 0)
205 return ret;
206 202
207 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM;203 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST | MIPI_DSI_MODE_LPM;
208 dsi->format = MIPI_DSI_FMT_RGB888;204 dsi->format = MIPI_DSI_FMT_RGB888;
drivers/gpu/drm/panel/panel-samsung-ld9040.c+4−3
@@ -21,7 +21,6 @@ · 20 unmodified lines
21 21
22#include <drm/drm_modes.h>22#include <drm/drm_modes.h>
23#include <drm/drm_panel.h>23#include <drm/drm_panel.h>
24#include <drm/drm_print.h>
25 24
26/* Manufacturer Command Set */25/* Manufacturer Command Set */
27#define MCS_MANPWR 0xb026#define MCS_MANPWR 0xb0
@@ -269,7 +268,7 @@ static int ld9040_get_modes(struct drm_panel *panel, · 241 unmodified lines
269 268
270 mode = drm_mode_create(connector->dev);269 mode = drm_mode_create(connector->dev);
271 if (!mode) {270 if (!mode) {
272 DRM_ERROR("failed to create a new display mode\n");271 dev_err(panel->dev, "failed to create a new display mode\n");
273 return 0;272 return 0;
274 }273 }
275 274
@@ -354,7 +353,9 @@ static int ld9040_probe(struct spi_device *spi) · 78 unmodified lines
354 drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs,353 drm_panel_init(&ctx->panel, dev, &ld9040_drm_funcs,
355 DRM_MODE_CONNECTOR_DPI);354 DRM_MODE_CONNECTOR_DPI);
356 355
357 return drm_panel_add(&ctx->panel);356 drm_panel_add(&ctx->panel);
357
358 return 0;
358}359}
359 360
360static int ld9040_remove(struct spi_device *spi)361static int ld9040_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-samsung-s6d16d0.c+9−18
@@ -7,7 +7,6 @@ · 6 unmodified lines
7#include <drm/drm_modes.h>7#include <drm/drm_modes.h>
8#include <drm/drm_mipi_dsi.h>8#include <drm/drm_mipi_dsi.h>
9#include <drm/drm_panel.h>9#include <drm/drm_panel.h>
10#include <drm/drm_print.h>
11 10
12#include <linux/gpio/consumer.h>11#include <linux/gpio/consumer.h>
13#include <linux/regulator/consumer.h>12#include <linux/regulator/consumer.h>
@@ -55,8 +54,7 @@ static int s6d16d0_unprepare(struct drm_panel *panel) · 41 unmodified lines
55 /* Enter sleep mode */54 /* Enter sleep mode */
56 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);55 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
57 if (ret) {56 if (ret) {
58 DRM_DEV_ERROR(s6->dev, "failed to enter sleep mode (%d)\n",57 dev_err(s6->dev, "failed to enter sleep mode (%d)\n", ret);
59 ret);
60 return ret;58 return ret;
61 }59 }
62 60
@@ -75,7 +73,7 @@ static int s6d16d0_prepare(struct drm_panel *panel) · 12 unmodified lines
75 73
76 ret = regulator_enable(s6->supply);74 ret = regulator_enable(s6->supply);
77 if (ret) {75 if (ret) {
78 DRM_DEV_ERROR(s6->dev, "failed to enable supply (%d)\n", ret);76 dev_err(s6->dev, "failed to enable supply (%d)\n", ret);
79 return ret;77 return ret;
80 }78 }
81 79
@@ -90,15 +88,13 @@ static int s6d16d0_prepare(struct drm_panel *panel) · 8 unmodified lines
90 ret = mipi_dsi_dcs_set_tear_on(dsi,88 ret = mipi_dsi_dcs_set_tear_on(dsi,
91 MIPI_DSI_DCS_TEAR_MODE_VBLANK);89 MIPI_DSI_DCS_TEAR_MODE_VBLANK);
92 if (ret) {90 if (ret) {
93 DRM_DEV_ERROR(s6->dev, "failed to enable vblank TE (%d)\n",91 dev_err(s6->dev, "failed to enable vblank TE (%d)\n", ret);
94 ret);
95 return ret;92 return ret;
96 }93 }
97 /* Exit sleep mode and power on */94 /* Exit sleep mode and power on */
98 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);95 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
99 if (ret) {96 if (ret) {
100 DRM_DEV_ERROR(s6->dev, "failed to exit sleep mode (%d)\n",97 dev_err(s6->dev, "failed to exit sleep mode (%d)\n", ret);
101 ret);
102 return ret;98 return ret;
103 }99 }
104 100
@@ -113,8 +109,7 @@ static int s6d16d0_enable(struct drm_panel *panel) · 8 unmodified lines
113 109
114 ret = mipi_dsi_dcs_set_display_on(dsi);110 ret = mipi_dsi_dcs_set_display_on(dsi);
115 if (ret) {111 if (ret) {
116 DRM_DEV_ERROR(s6->dev, "failed to turn display on (%d)\n",112 dev_err(s6->dev, "failed to turn display on (%d)\n", ret);
117 ret);
118 return ret;113 return ret;
119 }114 }
120 115
@@ -129,8 +124,7 @@ static int s6d16d0_disable(struct drm_panel *panel) · 8 unmodified lines
129 124
130 ret = mipi_dsi_dcs_set_display_off(dsi);125 ret = mipi_dsi_dcs_set_display_off(dsi);
131 if (ret) {126 if (ret) {
132 DRM_DEV_ERROR(s6->dev, "failed to turn display off (%d)\n",127 dev_err(s6->dev, "failed to turn display off (%d)\n", ret);
133 ret);
134 return ret;128 return ret;
135 }129 }
136 130
@@ -144,7 +138,7 @@ static int s6d16d0_get_modes(struct drm_panel *panel, · 7 unmodified lines
144 138
145 mode = drm_mode_duplicate(connector->dev, &samsung_s6d16d0_mode);139 mode = drm_mode_duplicate(connector->dev, &samsung_s6d16d0_mode);
146 if (!mode) {140 if (!mode) {
147 DRM_ERROR("bad mode or failed to add mode\n");141 dev_err(panel->dev, "bad mode or failed to add mode\n");
148 return -EINVAL;142 return -EINVAL;
149 }143 }
150 drm_mode_set_name(mode);144 drm_mode_set_name(mode);
@@ -204,17 +198,14 @@ static int s6d16d0_probe(struct mipi_dsi_device *dsi) · 53 unmodified lines
204 if (IS_ERR(s6->reset_gpio)) {198 if (IS_ERR(s6->reset_gpio)) {
205 ret = PTR_ERR(s6->reset_gpio);199 ret = PTR_ERR(s6->reset_gpio);
206 if (ret != -EPROBE_DEFER)200 if (ret != -EPROBE_DEFER)
207 DRM_DEV_ERROR(dev, "failed to request GPIO (%d)\n",201 dev_err(dev, "failed to request GPIO (%d)\n", ret);
208 ret);
209 return ret;202 return ret;
210 }203 }
211 204
212 drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs,205 drm_panel_init(&s6->panel, dev, &s6d16d0_drm_funcs,
213 DRM_MODE_CONNECTOR_DSI);206 DRM_MODE_CONNECTOR_DSI);
214 207
215 ret = drm_panel_add(&s6->panel);208 drm_panel_add(&s6->panel);
216 if (ret < 0)
217 return ret;
218 209
219 ret = mipi_dsi_attach(dsi);210 ret = mipi_dsi_attach(dsi);
220 if (ret < 0)211 if (ret < 0)
drivers/gpu/drm/panel/panel-samsung-s6e3ha2.c+2−7
@@ -18,7 +18,6 @@ · 17 unmodified lines
18#include <drm/drm_mipi_dsi.h>18#include <drm/drm_mipi_dsi.h>
19#include <drm/drm_modes.h>19#include <drm/drm_modes.h>
20#include <drm/drm_panel.h>20#include <drm/drm_panel.h>
21#include <drm/drm_print.h>
22 21
23#define S6E3HA2_MIN_BRIGHTNESS 022#define S6E3HA2_MIN_BRIGHTNESS 0
24#define S6E3HA2_MAX_BRIGHTNESS 10023#define S6E3HA2_MAX_BRIGHTNESS 100
@@ -651,7 +650,7 @@ static int s6e3ha2_get_modes(struct drm_panel *panel, · 626 unmodified lines
651 650
652 mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);651 mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
653 if (!mode) {652 if (!mode) {
654 DRM_ERROR("failed to add mode %ux%ux@%u\n",653 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
655 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,654 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
656 drm_mode_vrefresh(ctx->desc->mode));655 drm_mode_vrefresh(ctx->desc->mode));
657 return -ENOMEM;656 return -ENOMEM;
@@ -733,9 +732,7 @@ static int s6e3ha2_probe(struct mipi_dsi_device *dsi) · 75 unmodified lines
733 drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs,732 drm_panel_init(&ctx->panel, dev, &s6e3ha2_drm_funcs,
734 DRM_MODE_CONNECTOR_DSI);733 DRM_MODE_CONNECTOR_DSI);
735 734
736 ret = drm_panel_add(&ctx->panel);735 drm_panel_add(&ctx->panel);
737 if (ret < 0)
738 goto unregister_backlight;
739 736
740 ret = mipi_dsi_attach(dsi);737 ret = mipi_dsi_attach(dsi);
741 if (ret < 0)738 if (ret < 0)
@@ -745,8 +742,6 @@ static int s6e3ha2_probe(struct mipi_dsi_device *dsi) · 3 unmodified lines
745 742
746remove_panel:743remove_panel:
747 drm_panel_remove(&ctx->panel);744 drm_panel_remove(&ctx->panel);
748
749unregister_backlight:
750 backlight_device_unregister(ctx->bl_dev);745 backlight_device_unregister(ctx->bl_dev);
751 746
752 return ret;747 return ret;
drivers/gpu/drm/panel/panel-samsung-s6e63j0x03.c+2−7
@@ -19,7 +19,6 @@ · 18 unmodified lines
19#include <drm/drm_mipi_dsi.h>19#include <drm/drm_mipi_dsi.h>
20#include <drm/drm_modes.h>20#include <drm/drm_modes.h>
21#include <drm/drm_panel.h>21#include <drm/drm_panel.h>
22#include <drm/drm_print.h>
23 22
24#define MCS_LEVEL2_KEY 0xf023#define MCS_LEVEL2_KEY 0xf0
25#define MCS_MTP_KEY 0xf124#define MCS_MTP_KEY 0xf1
@@ -406,7 +405,7 @@ static int s6e63j0x03_get_modes(struct drm_panel *panel, · 380 unmodified lines
406 405
407 mode = drm_mode_duplicate(connector->dev, &default_mode);406 mode = drm_mode_duplicate(connector->dev, &default_mode);
408 if (!mode) {407 if (!mode) {
409 DRM_ERROR("failed to add mode %ux%ux@%u\n",408 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
410 default_mode.hdisplay, default_mode.vdisplay,409 default_mode.hdisplay, default_mode.vdisplay,
411 drm_mode_vrefresh(&default_mode));410 drm_mode_vrefresh(&default_mode));
412 return -ENOMEM;411 return -ENOMEM;
@@ -479,9 +478,7 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) · 66 unmodified lines
479 ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;478 ctx->bl_dev->props.brightness = DEFAULT_BRIGHTNESS;
480 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;479 ctx->bl_dev->props.power = FB_BLANK_POWERDOWN;
481 480
482 ret = drm_panel_add(&ctx->panel);481 drm_panel_add(&ctx->panel);
483 if (ret < 0)
484 goto unregister_backlight;
485 482
486 ret = mipi_dsi_attach(dsi);483 ret = mipi_dsi_attach(dsi);
487 if (ret < 0)484 if (ret < 0)
@@ -491,8 +488,6 @@ static int s6e63j0x03_probe(struct mipi_dsi_device *dsi) · 3 unmodified lines
491 488
492remove_panel:489remove_panel:
493 drm_panel_remove(&ctx->panel);490 drm_panel_remove(&ctx->panel);
494
495unregister_backlight:
496 backlight_device_unregister(ctx->bl_dev);491 backlight_device_unregister(ctx->bl_dev);
497 492
498 return ret;493 return ret;
drivers/gpu/drm/panel/panel-samsung-s6e63m0.c+12−14
@@ -10,7 +10,6 @@ · 9 unmodified lines
10 10
11#include <drm/drm_modes.h>11#include <drm/drm_modes.h>
12#include <drm/drm_panel.h>12#include <drm/drm_panel.h>
13#include <drm/drm_print.h>
14 13
15#include <linux/backlight.h>14#include <linux/backlight.h>
16#include <linux/delay.h>15#include <linux/delay.h>
@@ -157,7 +156,7 @@ static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len) · 140 unmodified lines
157 if (ctx->error < 0 || len == 0)156 if (ctx->error < 0 || len == 0)
158 return;157 return;
159 158
160 DRM_DEV_DEBUG(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data);159 dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data);
161 ret = s6e63m0_spi_write_word(ctx, *data);160 ret = s6e63m0_spi_write_word(ctx, *data);
162 161
163 while (!ret && --len) {162 while (!ret && --len) {
@@ -166,8 +165,7 @@ static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len) · 2 unmodified lines
166 }165 }
167 166
168 if (ret) {167 if (ret) {
169 DRM_DEV_ERROR(ctx->dev, "error %d writing dcs seq: %*ph\n", ret,168 dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, (int)len, data);
170 (int)len, data);
171 ctx->error = ret;169 ctx->error = ret;
172 }170 }
173 171
@@ -368,9 +366,9 @@ static int s6e63m0_get_modes(struct drm_panel *panel, · 194 unmodified lines
368 366
369 mode = drm_mode_duplicate(connector->dev, &default_mode);367 mode = drm_mode_duplicate(connector->dev, &default_mode);
370 if (!mode) {368 if (!mode) {
371 DRM_ERROR("failed to add mode %ux%ux@%u\n",369 dev_err(panel->dev, "failed to add mode %ux%u@%u\n",
372 default_mode.hdisplay, default_mode.vdisplay,370 default_mode.hdisplay, default_mode.vdisplay,
373 drm_mode_vrefresh(&default_mode));371 drm_mode_vrefresh(&default_mode));
374 return -ENOMEM;372 return -ENOMEM;
375 }373 }
376 374
@@ -425,8 +423,7 @@ static int s6e63m0_backlight_register(struct s6e63m0 *ctx) · 48 unmodified lines
425 &props);423 &props);
426 if (IS_ERR(ctx->bl_dev)) {424 if (IS_ERR(ctx->bl_dev)) {
427 ret = PTR_ERR(ctx->bl_dev);425 ret = PTR_ERR(ctx->bl_dev);
428 DRM_DEV_ERROR(dev, "error registering backlight device (%d)\n",426 dev_err(dev, "error registering backlight device (%d)\n", ret);
429 ret);
430 }427 }
431 428
432 return ret;429 return ret;
@@ -453,14 +450,13 @@ static int s6e63m0_probe(struct spi_device *spi) · 20 unmodified lines
453 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),450 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
454 ctx->supplies);451 ctx->supplies);
455 if (ret < 0) {452 if (ret < 0) {
456 DRM_DEV_ERROR(dev, "failed to get regulators: %d\n", ret);453 dev_err(dev, "failed to get regulators: %d\n", ret);
457 return ret;454 return ret;
458 }455 }
459 456
460 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);457 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
461 if (IS_ERR(ctx->reset_gpio)) {458 if (IS_ERR(ctx->reset_gpio)) {
462 DRM_DEV_ERROR(dev, "cannot get reset-gpios %ld\n",459 dev_err(dev, "cannot get reset-gpios %ld\n", PTR_ERR(ctx->reset_gpio));
463 PTR_ERR(ctx->reset_gpio));
464 return PTR_ERR(ctx->reset_gpio);460 return PTR_ERR(ctx->reset_gpio);
465 }461 }
466 462
@@ -468,7 +464,7 @@ static int s6e63m0_probe(struct spi_device *spi) · 1 unmodified line
468 spi->mode = SPI_MODE_3;464 spi->mode = SPI_MODE_3;
469 ret = spi_setup(spi);465 ret = spi_setup(spi);
470 if (ret < 0) {466 if (ret < 0) {
471 DRM_DEV_ERROR(dev, "spi setup failed.\n");467 dev_err(dev, "spi setup failed.\n");
472 return ret;468 return ret;
473 }469 }
474 470
@@ -479,7 +475,9 @@ static int s6e63m0_probe(struct spi_device *spi) · 4 unmodified lines
479 if (ret < 0)475 if (ret < 0)
480 return ret;476 return ret;
481 477
482 return drm_panel_add(&ctx->panel);478 drm_panel_add(&ctx->panel);
479
480 return 0;
483}481}
484 482
485static int s6e63m0_remove(struct spi_device *spi)483static int s6e63m0_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c+1−5
@@ -242,11 +242,7 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) · 241 unmodified lines
242 drm_panel_init(&ctx->panel, dev, &s6e88a0_ams452ef01_panel_funcs,242 drm_panel_init(&ctx->panel, dev, &s6e88a0_ams452ef01_panel_funcs,
243 DRM_MODE_CONNECTOR_DSI);243 DRM_MODE_CONNECTOR_DSI);
244 244
245 ret = drm_panel_add(&ctx->panel);245 drm_panel_add(&ctx->panel);
246 if (ret < 0) {
247 dev_err(dev, "Failed to add panel: %d\n", ret);
248 return ret;
249 }
250 246
251 ret = mipi_dsi_attach(dsi);247 ret = mipi_dsi_attach(dsi);
252 if (ret < 0) {248 if (ret < 0) {
drivers/gpu/drm/panel/panel-samsung-s6e8aa0.c+2−5
@@ -25,7 +25,6 @@ · 24 unmodified lines
25#include <drm/drm_mipi_dsi.h>25#include <drm/drm_mipi_dsi.h>
26#include <drm/drm_modes.h>26#include <drm/drm_modes.h>
27#include <drm/drm_panel.h>27#include <drm/drm_panel.h>
28#include <drm/drm_print.h>
29 28
30#define LDI_MTP_LENGTH 2429#define LDI_MTP_LENGTH 24
31#define GAMMA_LEVEL_NUM 2530#define GAMMA_LEVEL_NUM 25
@@ -928,7 +927,7 @@ static int s6e8aa0_get_modes(struct drm_panel *panel, · 896 unmodified lines
928 927
929 mode = drm_mode_create(connector->dev);928 mode = drm_mode_create(connector->dev);
930 if (!mode) {929 if (!mode) {
931 DRM_ERROR("failed to create a new display mode\n");930 dev_err(panel->dev, "failed to create a new display mode\n");
932 return 0;931 return 0;
933 }932 }
934 933
@@ -1020,9 +1019,7 @@ static int s6e8aa0_probe(struct mipi_dsi_device *dsi) · 85 unmodified lines
1020 drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,1019 drm_panel_init(&ctx->panel, dev, &s6e8aa0_drm_funcs,
1021 DRM_MODE_CONNECTOR_DSI);1020 DRM_MODE_CONNECTOR_DSI);
1022 1021
1023 ret = drm_panel_add(&ctx->panel);1022 drm_panel_add(&ctx->panel);
1024 if (ret < 0)
1025 return ret;
1026 1023
1027 ret = mipi_dsi_attach(dsi);1024 ret = mipi_dsi_attach(dsi);
1028 if (ret < 0)1025 if (ret < 0)
drivers/gpu/drm/panel/panel-seiko-43wvf1g.c+1−3
@@ -258,9 +258,7 @@ static int seiko_panel_probe(struct device *dev, · 257 unmodified lines
258 if (err)258 if (err)
259 return err;259 return err;
260 260
261 err = drm_panel_add(&panel->base);261 drm_panel_add(&panel->base);
262 if (err < 0)
263 return err;
264 262
265 dev_set_drvdata(dev, panel);263 dev_set_drvdata(dev, panel);
266 264
drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c+3−1
@@ -325,7 +325,9 @@ static int sharp_panel_add(struct sharp_panel *sharp) · 324 unmodified lines
325 if (ret)325 if (ret)
326 return ret;326 return ret;
327 327
328 return drm_panel_add(&sharp->base);328 drm_panel_add(&sharp->base);
329
330 return 0;
329}331}
330 332
331static void sharp_panel_del(struct sharp_panel *sharp)333static void sharp_panel_del(struct sharp_panel *sharp)
drivers/gpu/drm/panel/panel-sharp-ls037v7dw01.c+3−1
@@ -187,7 +187,9 @@ static int ls037v7dw01_probe(struct platform_device *pdev) · 186 unmodified lines
187 drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs,187 drm_panel_init(&lcd->panel, &pdev->dev, &ls037v7dw01_funcs,
188 DRM_MODE_CONNECTOR_DPI);188 DRM_MODE_CONNECTOR_DPI);
189 189
190 return drm_panel_add(&lcd->panel);190 drm_panel_add(&lcd->panel);
191
192 return 0;
191}193}
192 194
193static int ls037v7dw01_remove(struct platform_device *pdev)195static int ls037v7dw01_remove(struct platform_device *pdev)
drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c+3−1
@@ -261,7 +261,9 @@ static int sharp_nt_panel_add(struct sharp_nt_panel *sharp_nt) · 260 unmodified lines
261 if (ret)261 if (ret)
262 return ret;262 return ret;
263 263
264 return drm_panel_add(&sharp_nt->base);264 drm_panel_add(&sharp_nt->base);
265
266 return 0;
265}267}
266 268
267static void sharp_nt_panel_del(struct sharp_nt_panel *sharp_nt)269static void sharp_nt_panel_del(struct sharp_nt_panel *sharp_nt)
drivers/gpu/drm/panel/panel-simple.c+180−21
@@ -112,6 +112,8 @@ struct panel_simple { · 111 unmodified lines
112 struct gpio_desc *hpd_gpio;112 struct gpio_desc *hpd_gpio;
113 113
114 struct drm_display_mode override_mode;114 struct drm_display_mode override_mode;
115
116 enum drm_panel_orientation orientation;
115};117};
116 118
117static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)119static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
@@ -371,6 +373,9 @@ static int panel_simple_get_modes(struct drm_panel *panel, · 253 unmodified lines
371 /* add hard-coded panel modes */373 /* add hard-coded panel modes */
372 num += panel_simple_get_non_edid_modes(p, connector);374 num += panel_simple_get_non_edid_modes(p, connector);
373 375
376 /* set up connector's "panel orientation" property */
377 drm_connector_set_panel_orientation(connector, p->orientation);
378
374 return num;379 return num;
375}380}
376 381
@@ -500,6 +505,8 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) · 123 unmodified lines
500 struct panel_simple *panel;505 struct panel_simple *panel;
501 struct display_timing dt;506 struct display_timing dt;
502 struct device_node *ddc;507 struct device_node *ddc;
508 int connector_type;
509 u32 bus_flags;
503 int err;510 int err;
504 511
505 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);512 panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL);
@@ -530,6 +537,12 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) · 24 unmodified lines
530 return err;537 return err;
531 }538 }
532 539
540 err = of_drm_get_panel_orientation(dev->of_node, &panel->orientation);
541 if (err) {
542 dev_err(dev, "%pOF: failed to get orientation %d\n", dev->of_node, err);
543 return err;
544 }
545
533 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);546 ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);
534 if (ddc) {547 if (ddc) {
535 panel->ddc = of_find_i2c_adapter_by_node(ddc);548 panel->ddc = of_find_i2c_adapter_by_node(ddc);
@@ -549,8 +562,14 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) · 13 unmodified lines
549 panel_simple_parse_panel_timing_node(dev, panel, &dt);562 panel_simple_parse_panel_timing_node(dev, panel, &dt);
550 }563 }
551 564
552 if (desc->connector_type == DRM_MODE_CONNECTOR_LVDS) {565 connector_type = desc->connector_type;
553 /* Catch common mistakes for LVDS panels. */566 /* Catch common mistakes for panels. */
567 switch (connector_type) {
568 case 0:
569 dev_warn(dev, "Specify missing connector_type\n");
570 connector_type = DRM_MODE_CONNECTOR_DPI;
571 break;
572 case DRM_MODE_CONNECTOR_LVDS:
554 WARN_ON(desc->bus_flags &573 WARN_ON(desc->bus_flags &
555 ~(DRM_BUS_FLAG_DE_LOW |574 ~(DRM_BUS_FLAG_DE_LOW |
556 DRM_BUS_FLAG_DE_HIGH |575 DRM_BUS_FLAG_DE_HIGH |
@@ -564,18 +583,48 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) · 7 unmodified lines
564 WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||583 WARN_ON((desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_SPWG ||
565 desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&584 desc->bus_format == MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA) &&
566 desc->bpc != 8);585 desc->bpc != 8);
586 break;
587 case DRM_MODE_CONNECTOR_eDP:
588 if (desc->bus_format == 0)
589 dev_warn(dev, "Specify missing bus_format\n");
590 if (desc->bpc != 6 && desc->bpc != 8)
591 dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
592 break;
593 case DRM_MODE_CONNECTOR_DSI:
594 if (desc->bpc != 6 && desc->bpc != 8)
595 dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
596 break;
597 case DRM_MODE_CONNECTOR_DPI:
598 bus_flags = DRM_BUS_FLAG_DE_LOW |
599 DRM_BUS_FLAG_DE_HIGH |
600 DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE |
601 DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
602 DRM_BUS_FLAG_DATA_MSB_TO_LSB |
603 DRM_BUS_FLAG_DATA_LSB_TO_MSB |
604 DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE |
605 DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
606 if (desc->bus_flags & ~bus_flags)
607 dev_warn(dev, "Unexpected bus_flags(%d)\n", desc->bus_flags & ~bus_flags);
608 if (!(desc->bus_flags & bus_flags))
609 dev_warn(dev, "Specify missing bus_flags\n");
610 if (desc->bus_format == 0)
611 dev_warn(dev, "Specify missing bus_format\n");
612 if (desc->bpc != 6 && desc->bpc != 8)
613 dev_warn(dev, "Expected bpc in {6,8} but got: %u\n", desc->bpc);
614 break;
615 default:
616 dev_warn(dev, "Specify a valid connector_type: %d\n", desc->connector_type);
617 connector_type = DRM_MODE_CONNECTOR_DPI;
618 break;
567 }619 }
568 620
569 drm_panel_init(&panel->base, dev, &panel_simple_funcs,621 drm_panel_init(&panel->base, dev, &panel_simple_funcs, connector_type);
570 desc->connector_type);
571 622
572 err = drm_panel_of_backlight(&panel->base);623 err = drm_panel_of_backlight(&panel->base);
573 if (err)624 if (err)
574 goto free_ddc;625 goto free_ddc;
575 626
576 err = drm_panel_add(&panel->base);627 drm_panel_add(&panel->base);
577 if (err < 0)
578 goto free_ddc;
579 628
580 dev_set_drvdata(dev, panel);629 dev_set_drvdata(dev, panel);
581 630
@@ -1191,10 +1240,14 @@ static const struct drm_display_mode boe_hv070wsa_mode = { · 609 unmodified lines
1191static const struct panel_desc boe_hv070wsa = {1240static const struct panel_desc boe_hv070wsa = {
1192 .modes = &boe_hv070wsa_mode,1241 .modes = &boe_hv070wsa_mode,
1193 .num_modes = 1,1242 .num_modes = 1,
1243 .bpc = 8,
1194 .size = {1244 .size = {
1195 .width = 154,1245 .width = 154,
1196 .height = 90,1246 .height = 90,
1197 },1247 },
1248 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1249 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
1250 .connector_type = DRM_MODE_CONNECTOR_LVDS,
1198};1251};
1199 1252
1200static const struct drm_display_mode boe_nv101wxmn51_modes[] = {1253static const struct drm_display_mode boe_nv101wxmn51_modes[] = {
@@ -1414,6 +1467,36 @@ static const struct panel_desc cdtech_s070wv95_ct16 = { · 213 unmodified lines
1414 },1467 },
1415};1468};
1416 1469
1470static const struct display_timing chefree_ch101olhlwh_002_timing = {
1471 .pixelclock = { 68900000, 71100000, 73400000 },
1472 .hactive = { 1280, 1280, 1280 },
1473 .hfront_porch = { 65, 80, 95 },
1474 .hback_porch = { 64, 79, 94 },
1475 .hsync_len = { 1, 1, 1 },
1476 .vactive = { 800, 800, 800 },
1477 .vfront_porch = { 7, 11, 14 },
1478 .vback_porch = { 7, 11, 14 },
1479 .vsync_len = { 1, 1, 1 },
1480 .flags = DISPLAY_FLAGS_DE_HIGH,
1481};
1482
1483static const struct panel_desc chefree_ch101olhlwh_002 = {
1484 .timings = &chefree_ch101olhlwh_002_timing,
1485 .num_timings = 1,
1486 .bpc = 8,
1487 .size = {
1488 .width = 217,
1489 .height = 135,
1490 },
1491 .delay = {
1492 .enable = 200,
1493 .disable = 200,
1494 },
1495 .bus_flags = DRM_BUS_FLAG_DE_HIGH,
1496 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
1497 .connector_type = DRM_MODE_CONNECTOR_LVDS,
1498};
1499
1417static const struct drm_display_mode chunghwa_claa070wp03xg_mode = {1500static const struct drm_display_mode chunghwa_claa070wp03xg_mode = {
1418 .clock = 66770,1501 .clock = 66770,
1419 .hdisplay = 800,1502 .hdisplay = 800,
@@ -2258,6 +2341,34 @@ static const struct panel_desc ivo_m133nwf4_r0 = { · 838 unmodified lines
2258 .connector_type = DRM_MODE_CONNECTOR_eDP,2341 .connector_type = DRM_MODE_CONNECTOR_eDP,
2259};2342};
2260 2343
2344static const struct drm_display_mode kingdisplay_kd116n21_30nv_a010_mode = {
2345 .clock = 81000,
2346 .hdisplay = 1366,
2347 .hsync_start = 1366 + 40,
2348 .hsync_end = 1366 + 40 + 32,
2349 .htotal = 1366 + 40 + 32 + 62,
2350 .vdisplay = 768,
2351 .vsync_start = 768 + 5,
2352 .vsync_end = 768 + 5 + 5,
2353 .vtotal = 768 + 5 + 5 + 122,
2354 .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
2355};
2356
2357static const struct panel_desc kingdisplay_kd116n21_30nv_a010 = {
2358 .modes = &kingdisplay_kd116n21_30nv_a010_mode,
2359 .num_modes = 1,
2360 .bpc = 6,
2361 .size = {
2362 .width = 256,
2363 .height = 144,
2364 },
2365 .delay = {
2366 .hpd_absent_delay = 200,
2367 },
2368 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
2369 .connector_type = DRM_MODE_CONNECTOR_eDP,
2370};
2371
2261static const struct display_timing koe_tx14d24vm1bpa_timing = {2372static const struct display_timing koe_tx14d24vm1bpa_timing = {
2262 .pixelclock = { 5580000, 5850000, 6200000 },2373 .pixelclock = { 5580000, 5850000, 6200000 },
2263 .hactive = { 320, 320, 320 },2374 .hactive = { 320, 320, 320 },
@@ -2946,7 +3057,7 @@ static const struct panel_desc ortustech_com43h4m85ulc = { · 682 unmodified lines
2946 .width = 56,3057 .width = 56,
2947 .height = 93,3058 .height = 93,
2948 },3059 },
2949 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,3060 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
2950 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,3061 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
2951 .connector_type = DRM_MODE_CONNECTOR_DPI,3062 .connector_type = DRM_MODE_CONNECTOR_DPI,
2952};3063};
@@ -3000,6 +3111,31 @@ static const struct panel_desc pda_91_00156_a0 = { · 47 unmodified lines
3000 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,3111 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
3001};3112};
3002 3113
3114static const struct drm_display_mode powertip_ph800480t013_idf02_mode = {
3115 .clock = 24750,
3116 .hdisplay = 800,
3117 .hsync_start = 800 + 54,
3118 .hsync_end = 800 + 54 + 2,
3119 .htotal = 800 + 54 + 2 + 44,
3120 .vdisplay = 480,
3121 .vsync_start = 480 + 49,
3122 .vsync_end = 480 + 49 + 2,
3123 .vtotal = 480 + 49 + 2 + 22,
3124};
3125
3126static const struct panel_desc powertip_ph800480t013_idf02 = {
3127 .modes = &powertip_ph800480t013_idf02_mode,
3128 .num_modes = 1,
3129 .size = {
3130 .width = 152,
3131 .height = 91,
3132 },
3133 .bus_flags = DRM_BUS_FLAG_DE_HIGH |
3134 DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE |
3135 DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE,
3136 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
3137 .connector_type = DRM_MODE_CONNECTOR_DPI,
3138};
3003 3139
3004static const struct drm_display_mode qd43003c0_40_mode = {3140static const struct drm_display_mode qd43003c0_40_mode = {
3005 .clock = 9000,3141 .clock = 9000,
@@ -3301,22 +3437,36 @@ static const struct panel_desc sharp_lq123p1jx31 = { · 295 unmodified lines
3301 },3437 },
3302};3438};
3303 3439
3304static const struct display_timing sharp_ls020b1dd01d_timing = {3440static const struct drm_display_mode sharp_ls020b1dd01d_modes[] = {
3305 .pixelclock = { 2000000, 4200000, 5000000 },3441 { /* 50 Hz */
3306 .hactive = { 240, 240, 240 },3442 .clock = 3000,
3307 .hfront_porch = { 66, 66, 66 },3443 .hdisplay = 240,
3308 .hback_porch = { 1, 1, 1 },3444 .hsync_start = 240 + 58,
3309 .hsync_len = { 1, 1, 1 },3445 .hsync_end = 240 + 58 + 1,
3310 .vactive = { 160, 160, 160 },3446 .htotal = 240 + 58 + 1 + 1,
3311 .vfront_porch = { 52, 52, 52 },3447 .vdisplay = 160,
3312 .vback_porch = { 6, 6, 6 },3448 .vsync_start = 160 + 24,
3313 .vsync_len = { 10, 10, 10 },3449 .vsync_end = 160 + 24 + 10,
3314 .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_LOW,3450 .vtotal = 160 + 24 + 10 + 6,
3451 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC,
3452 },
3453 { /* 60 Hz */
3454 .clock = 3000,
3455 .hdisplay = 240,
3456 .hsync_start = 240 + 8,
3457 .hsync_end = 240 + 8 + 1,
3458 .htotal = 240 + 8 + 1 + 1,
3459 .vdisplay = 160,
3460 .vsync_start = 160 + 24,
3461 .vsync_end = 160 + 24 + 10,
3462 .vtotal = 160 + 24 + 10 + 6,
3463 .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC,
3464 },
3315};3465};
3316 3466
3317static const struct panel_desc sharp_ls020b1dd01d = {3467static const struct panel_desc sharp_ls020b1dd01d = {
3318 .timings = &sharp_ls020b1dd01d_timing,3468 .modes = sharp_ls020b1dd01d_modes,
3319 .num_timings = 1,3469 .num_modes = ARRAY_SIZE(sharp_ls020b1dd01d_modes),
3320 .bpc = 6,3470 .bpc = 6,
3321 .size = {3471 .size = {
3322 .width = 42,3472 .width = 42,
@@ -3820,6 +3970,9 @@ static const struct of_device_id platform_of_match[] = { · 497 unmodified lines
3820 }, {3970 }, {
3821 .compatible = "cdtech,s070wv95-ct16",3971 .compatible = "cdtech,s070wv95-ct16",
3822 .data = &cdtech_s070wv95_ct16,3972 .data = &cdtech_s070wv95_ct16,
3973 }, {
3974 .compatible = "chefree,ch101olhlwh-002",
3975 .data = &chefree_ch101olhlwh_002,
3823 }, {3976 }, {
3824 .compatible = "chunghwa,claa070wp03xg",3977 .compatible = "chunghwa,claa070wp03xg",
3825 .data = &chunghwa_claa070wp03xg,3978 .data = &chunghwa_claa070wp03xg,
@@ -3922,6 +4075,9 @@ static const struct of_device_id platform_of_match[] = { · 96 unmodified lines
3922 }, {4075 }, {
3923 .compatible = "ivo,m133nwf4-r0",4076 .compatible = "ivo,m133nwf4-r0",
3924 .data = &ivo_m133nwf4_r0,4077 .data = &ivo_m133nwf4_r0,
4078 }, {
4079 .compatible = "kingdisplay,kd116n21-30nv-a010",
4080 .data = &kingdisplay_kd116n21_30nv_a010,
3925 }, {4081 }, {
3926 .compatible = "koe,tx14d24vm1bpa",4082 .compatible = "koe,tx14d24vm1bpa",
3927 .data = &koe_tx14d24vm1bpa,4083 .data = &koe_tx14d24vm1bpa,
@@ -4012,6 +4168,9 @@ static const struct of_device_id platform_of_match[] = { · 84 unmodified lines
4012 }, {4168 }, {
4013 .compatible = "pda,91-00156-a0",4169 .compatible = "pda,91-00156-a0",
4014 .data = &pda_91_00156_a0,4170 .data = &pda_91_00156_a0,
4171 }, {
4172 .compatible = "powertip,ph800480t013-idf02",
4173 .data = &powertip_ph800480t013_idf02,
4015 }, {4174 }, {
4016 .compatible = "qiaodian,qd43003c0-40",4175 .compatible = "qiaodian,qd43003c0-40",
4017 .data = &qd43003c0_40,4176 .data = &qd43003c0_40,
drivers/gpu/drm/panel/panel-sitronix-st7701.c+5−9
@@ -7,7 +7,6 @@ · 6 unmodified lines
7#include <drm/drm_mipi_dsi.h>7#include <drm/drm_mipi_dsi.h>
8#include <drm/drm_modes.h>8#include <drm/drm_modes.h>
9#include <drm/drm_panel.h>9#include <drm/drm_panel.h>
10#include <drm/drm_print.h>
11 10
12#include <linux/gpio/consumer.h>11#include <linux/gpio/consumer.h>
13#include <linux/delay.h>12#include <linux/delay.h>
@@ -269,10 +268,9 @@ static int st7701_get_modes(struct drm_panel *panel, · 255 unmodified lines
269 268
270 mode = drm_mode_duplicate(connector->dev, desc_mode);269 mode = drm_mode_duplicate(connector->dev, desc_mode);
271 if (!mode) {270 if (!mode) {
272 DRM_DEV_ERROR(&st7701->dsi->dev,271 dev_err(&st7701->dsi->dev, "failed to add mode %ux%u@%u\n",
273 "failed to add mode %ux%ux@%u\n",272 desc_mode->hdisplay, desc_mode->vdisplay,
274 desc_mode->hdisplay, desc_mode->vdisplay,273 drm_mode_vrefresh(desc_mode));
275 drm_mode_vrefresh(desc_mode));
276 return -ENOMEM;274 return -ENOMEM;
277 }275 }
278 276
@@ -358,7 +356,7 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi) · 79 unmodified lines
358 356
359 st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);357 st7701->reset = devm_gpiod_get(&dsi->dev, "reset", GPIOD_OUT_LOW);
360 if (IS_ERR(st7701->reset)) {358 if (IS_ERR(st7701->reset)) {
361 DRM_DEV_ERROR(&dsi->dev, "Couldn't get our reset GPIO\n");359 dev_err(&dsi->dev, "Couldn't get our reset GPIO\n");
362 return PTR_ERR(st7701->reset);360 return PTR_ERR(st7701->reset);
363 }361 }
364 362
@@ -380,9 +378,7 @@ static int st7701_dsi_probe(struct mipi_dsi_device *dsi) · 15 unmodified lines
380 if (ret)378 if (ret)
381 return ret;379 return ret;
382 380
383 ret = drm_panel_add(&st7701->panel);381 drm_panel_add(&st7701->panel);
384 if (ret < 0)
385 return ret;
386 382
387 mipi_dsi_set_drvdata(dsi, st7701);383 mipi_dsi_set_drvdata(dsi, st7701);
388 st7701->dsi = dsi;384 st7701->dsi = dsi;
drivers/gpu/drm/panel/panel-sitronix-st7703.c+23−38
@@ -22,7 +22,6 @@ · 21 unmodified lines
22#include <drm/drm_mipi_dsi.h>22#include <drm/drm_mipi_dsi.h>
23#include <drm/drm_modes.h>23#include <drm/drm_modes.h>
24#include <drm/drm_panel.h>24#include <drm/drm_panel.h>
25#include <drm/drm_print.h>
26 25
27#define DRV_NAME "panel-sitronix-st7703"26#define DRV_NAME "panel-sitronix-st7703"
28 27
@@ -364,8 +363,7 @@ static int st7703_enable(struct drm_panel *panel) · 335 unmodified lines
364 363
365 ret = ctx->desc->init_sequence(ctx);364 ret = ctx->desc->init_sequence(ctx);
366 if (ret < 0) {365 if (ret < 0) {
367 DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",366 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
368 ret);
369 return ret;367 return ret;
370 }368 }
371 369
@@ -373,7 +371,7 @@ static int st7703_enable(struct drm_panel *panel) · 1 unmodified line
373 371
374 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);372 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
375 if (ret < 0) {373 if (ret < 0) {
376 DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);374 dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
377 return ret;375 return ret;
378 }376 }
379 377
@@ -384,7 +382,7 @@ static int st7703_enable(struct drm_panel *panel) · 4 unmodified lines
384 if (ret)382 if (ret)
385 return ret;383 return ret;
386 384
387 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Panel init sequence done\n");385 dev_dbg(ctx->dev, "Panel init sequence done\n");
388 386
389 return 0;387 return 0;
390}388}
@@ -397,13 +395,11 @@ static int st7703_disable(struct drm_panel *panel) · 6 unmodified lines
397 395
398 ret = mipi_dsi_dcs_set_display_off(dsi);396 ret = mipi_dsi_dcs_set_display_off(dsi);
399 if (ret < 0)397 if (ret < 0)
400 DRM_DEV_ERROR(ctx->dev,398 dev_err(ctx->dev, "Failed to turn off the display: %d\n", ret);
401 "Failed to turn off the display: %d\n", ret);
402 399
403 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);400 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
404 if (ret < 0)401 if (ret < 0)
405 DRM_DEV_ERROR(ctx->dev,402 dev_err(ctx->dev, "Failed to enter sleep mode: %d\n", ret);
406 "Failed to enter sleep mode: %d\n", ret);
407 403
408 return 0;404 return 0;
409}405}
@@ -431,17 +427,15 @@ static int st7703_prepare(struct drm_panel *panel) · 21 unmodified lines
431 if (ctx->prepared)427 if (ctx->prepared)
432 return 0;428 return 0;
433 429
434 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");430 dev_dbg(ctx->dev, "Resetting the panel\n");
435 ret = regulator_enable(ctx->vcc);431 ret = regulator_enable(ctx->vcc);
436 if (ret < 0) {432 if (ret < 0) {
437 DRM_DEV_ERROR(ctx->dev,433 dev_err(ctx->dev, "Failed to enable vcc supply: %d\n", ret);
438 "Failed to enable vcc supply: %d\n", ret);
439 return ret;434 return ret;
440 }435 }
441 ret = regulator_enable(ctx->iovcc);436 ret = regulator_enable(ctx->iovcc);
442 if (ret < 0) {437 if (ret < 0) {
443 DRM_DEV_ERROR(ctx->dev,438 dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
444 "Failed to enable iovcc supply: %d\n", ret);
445 goto disable_vcc;439 goto disable_vcc;
446 }440 }
447 441
@@ -467,9 +461,9 @@ static int st7703_get_modes(struct drm_panel *panel, · 19 unmodified lines
467 461
468 mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);462 mode = drm_mode_duplicate(connector->dev, ctx->desc->mode);
469 if (!mode) {463 if (!mode) {
470 DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n",464 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
471 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,465 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
472 drm_mode_vrefresh(ctx->desc->mode));466 drm_mode_vrefresh(ctx->desc->mode));
473 return -ENOMEM;467 return -ENOMEM;
474 }468 }
475 469
@@ -496,7 +490,7 @@ static int allpixelson_set(void *data, u64 val) · 20 unmodified lines
496 struct st7703 *ctx = data;490 struct st7703 *ctx = data;
497 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);491 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev);
498 492
499 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Setting all pixels on\n");493 dev_dbg(ctx->dev, "Setting all pixels on\n");
500 dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON);494 dsi_generic_write_seq(dsi, ST7703_CMD_ALL_PIXEL_ON);
501 msleep(val * 1000);495 msleep(val * 1000);
502 /* Reset the panel to get video back */496 /* Reset the panel to get video back */
@@ -537,7 +531,7 @@ static int st7703_probe(struct mipi_dsi_device *dsi) · 34 unmodified lines
537 531
538 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);532 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
539 if (IS_ERR(ctx->reset_gpio)) {533 if (IS_ERR(ctx->reset_gpio)) {
540 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");534 dev_err(dev, "cannot get reset gpio\n");
541 return PTR_ERR(ctx->reset_gpio);535 return PTR_ERR(ctx->reset_gpio);
542 }536 }
543 537
@@ -554,18 +548,14 @@ static int st7703_probe(struct mipi_dsi_device *dsi) · 10 unmodified lines
554 if (IS_ERR(ctx->vcc)) {548 if (IS_ERR(ctx->vcc)) {
555 ret = PTR_ERR(ctx->vcc);549 ret = PTR_ERR(ctx->vcc);
556 if (ret != -EPROBE_DEFER)550 if (ret != -EPROBE_DEFER)
557 DRM_DEV_ERROR(dev,551 dev_err(dev, "Failed to request vcc regulator: %d\n", ret);
558 "Failed to request vcc regulator: %d\n",
559 ret);
560 return ret;552 return ret;
561 }553 }
562 ctx->iovcc = devm_regulator_get(dev, "iovcc");554 ctx->iovcc = devm_regulator_get(dev, "iovcc");
563 if (IS_ERR(ctx->iovcc)) {555 if (IS_ERR(ctx->iovcc)) {
564 ret = PTR_ERR(ctx->iovcc);556 ret = PTR_ERR(ctx->iovcc);
565 if (ret != -EPROBE_DEFER)557 if (ret != -EPROBE_DEFER)
566 DRM_DEV_ERROR(dev,558 dev_err(dev, "Failed to request iovcc regulator: %d\n", ret);
567 "Failed to request iovcc regulator: %d\n",
568 ret);
569 return ret;559 return ret;
570 }560 }
571 561
@@ -580,17 +570,15 @@ static int st7703_probe(struct mipi_dsi_device *dsi) · 8 unmodified lines
580 570
581 ret = mipi_dsi_attach(dsi);571 ret = mipi_dsi_attach(dsi);
582 if (ret < 0) {572 if (ret < 0) {
583 DRM_DEV_ERROR(dev,573 dev_err(dev, "mipi_dsi_attach failed (%d). Is host ready?\n", ret);
584 "mipi_dsi_attach failed (%d). Is host ready?\n",
585 ret);
586 drm_panel_remove(&ctx->panel);574 drm_panel_remove(&ctx->panel);
587 return ret;575 return ret;
588 }576 }
589 577
590 DRM_DEV_INFO(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",578 dev_info(dev, "%ux%u@%u %ubpp dsi %udl - ready\n",
591 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,579 ctx->desc->mode->hdisplay, ctx->desc->mode->vdisplay,
592 drm_mode_vrefresh(ctx->desc->mode),580 drm_mode_vrefresh(ctx->desc->mode),
593 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);581 mipi_dsi_pixel_format_to_bpp(dsi->format), dsi->lanes);
594 582
595 st7703_debugfs_init(ctx);583 st7703_debugfs_init(ctx);
596 return 0;584 return 0;
@@ -603,13 +591,11 @@ static void st7703_shutdown(struct mipi_dsi_device *dsi) · 6 unmodified lines
603 591
604 ret = drm_panel_unprepare(&ctx->panel);592 ret = drm_panel_unprepare(&ctx->panel);
605 if (ret < 0)593 if (ret < 0)
606 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",594 dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
607 ret);
608 595
609 ret = drm_panel_disable(&ctx->panel);596 ret = drm_panel_disable(&ctx->panel);
610 if (ret < 0)597 if (ret < 0)
611 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",598 dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
612 ret);
613}599}
614 600
615static int st7703_remove(struct mipi_dsi_device *dsi)601static int st7703_remove(struct mipi_dsi_device *dsi)
@@ -621,8 +607,7 @@ static int st7703_remove(struct mipi_dsi_device *dsi) · 5 unmodified lines
621 607
622 ret = mipi_dsi_detach(dsi);608 ret = mipi_dsi_detach(dsi);
623 if (ret < 0)609 if (ret < 0)
624 DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",610 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
625 ret);
626 611
627 drm_panel_remove(&ctx->panel);612 drm_panel_remove(&ctx->panel);
628 613
drivers/gpu/drm/panel/panel-sitronix-st7789v.c+1−3
@@ -382,9 +382,7 @@ static int st7789v_probe(struct spi_device *spi) · 381 unmodified lines
382 if (ret)382 if (ret)
383 return ret;383 return ret;
384 384
385 ret = drm_panel_add(&ctx->panel);385 drm_panel_add(&ctx->panel);
386 if (ret < 0)
387 return ret;
388 386
389 return 0;387 return 0;
390}388}
drivers/gpu/drm/panel/panel-sony-acx424akp.c+29−56
@@ -20,7 +20,6 @@ · 19 unmodified lines
20#include <drm/drm_mipi_dsi.h>20#include <drm/drm_mipi_dsi.h>
21#include <drm/drm_modes.h>21#include <drm/drm_modes.h>
22#include <drm/drm_panel.h>22#include <drm/drm_panel.h>
23#include <drm/drm_print.h>
24 23
25#define ACX424_DCS_READ_ID1 0xDA24#define ACX424_DCS_READ_ID1 0xDA
26#define ACX424_DCS_READ_ID2 0xDB25#define ACX424_DCS_READ_ID2 0xDB
@@ -110,13 +109,11 @@ static int acx424akp_set_brightness(struct backlight_device *bl) · 83 unmodified lines
110 SCALE_FACTOR_NS_DIV_MHZ);109 SCALE_FACTOR_NS_DIV_MHZ);
111 110
112 /* Set up PWM dutycycle ONE byte (differs from the standard) */111 /* Set up PWM dutycycle ONE byte (differs from the standard) */
113 DRM_DEV_DEBUG(acx->dev, "calculated duty cycle %02x\n", pwm_ratio);112 dev_dbg(acx->dev, "calculated duty cycle %02x\n", pwm_ratio);
114 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,113 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_BRIGHTNESS,
115 &pwm_ratio, 1);114 &pwm_ratio, 1);
116 if (ret < 0) {115 if (ret < 0) {
117 DRM_DEV_ERROR(acx->dev,116 dev_err(acx->dev, "failed to set display PWM ratio (%d)\n", ret);
118 "failed to set display PWM ratio (%d)\n",
119 ret);
120 return ret;117 return ret;
121 }118 }
122 119
@@ -132,40 +129,30 @@ static int acx424akp_set_brightness(struct backlight_device *bl) · 9 unmodified lines
132 par = 0xaa;129 par = 0xaa;
133 ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);130 ret = mipi_dsi_dcs_write(dsi, 0xf3, &par, 1);
134 if (ret < 0) {131 if (ret < 0) {
135 DRM_DEV_ERROR(acx->dev,132 dev_err(acx->dev, "failed to unlock CMD 2 (%d)\n", ret);
136 "failed to unlock CMD 2 (%d)\n",
137 ret);
138 return ret;133 return ret;
139 }134 }
140 par = 0x01;135 par = 0x01;
141 ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);136 ret = mipi_dsi_dcs_write(dsi, 0x00, &par, 1);
142 if (ret < 0) {137 if (ret < 0) {
143 DRM_DEV_ERROR(acx->dev,138 dev_err(acx->dev, "failed to enter page 1 (%d)\n", ret);
144 "failed to enter page 1 (%d)\n",
145 ret);
146 return ret;139 return ret;
147 }140 }
148 par = 0x01;141 par = 0x01;
149 ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);142 ret = mipi_dsi_dcs_write(dsi, 0x7d, &par, 1);
150 if (ret < 0) {143 if (ret < 0) {
151 DRM_DEV_ERROR(acx->dev,144 dev_err(acx->dev, "failed to disable MTP reload (%d)\n", ret);
152 "failed to disable MTP reload (%d)\n",
153 ret);
154 return ret;145 return ret;
155 }146 }
156 ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);147 ret = mipi_dsi_dcs_write(dsi, 0x22, &pwm_div, 1);
157 if (ret < 0) {148 if (ret < 0) {
158 DRM_DEV_ERROR(acx->dev,149 dev_err(acx->dev, "failed to set PWM divisor (%d)\n", ret);
159 "failed to set PWM divisor (%d)\n",
160 ret);
161 return ret;150 return ret;
162 }151 }
163 par = 0xaa;152 par = 0xaa;
164 ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);153 ret = mipi_dsi_dcs_write(dsi, 0x7f, &par, 1);
165 if (ret < 0) {154 if (ret < 0) {
166 DRM_DEV_ERROR(acx->dev,155 dev_err(acx->dev, "failed to lock CMD 2 (%d)\n", ret);
167 "failed to lock CMD 2 (%d)\n",
168 ret);
169 return ret;156 return ret;
170 }157 }
171 158
@@ -174,9 +161,7 @@ static int acx424akp_set_brightness(struct backlight_device *bl) · 2 unmodified lines
174 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,161 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
175 &par, 1);162 &par, 1);
176 if (ret < 0) {163 if (ret < 0) {
177 DRM_DEV_ERROR(acx->dev,164 dev_err(acx->dev, "failed to enable display backlight (%d)\n", ret);
178 "failed to enable display backlight (%d)\n",
179 ret);
180 return ret;165 return ret;
181 }166 }
182 167
@@ -196,22 +181,22 @@ static int acx424akp_read_id(struct acx424akp *acx) · 13 unmodified lines
196 181
197 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID1, &vendor, 1);182 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID1, &vendor, 1);
198 if (ret < 0) {183 if (ret < 0) {
199 DRM_DEV_ERROR(acx->dev, "could not vendor ID byte\n");184 dev_err(acx->dev, "could not vendor ID byte\n");
200 return ret;185 return ret;
201 }186 }
202 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID2, &version, 1);187 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID2, &version, 1);
203 if (ret < 0) {188 if (ret < 0) {
204 DRM_DEV_ERROR(acx->dev, "could not read device version byte\n");189 dev_err(acx->dev, "could not read device version byte\n");
205 return ret;190 return ret;
206 }191 }
207 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID3, &panel, 1);192 ret = mipi_dsi_dcs_read(dsi, ACX424_DCS_READ_ID3, &panel, 1);
208 if (ret < 0) {193 if (ret < 0) {
209 DRM_DEV_ERROR(acx->dev, "could not read panel ID byte\n");194 dev_err(acx->dev, "could not read panel ID byte\n");
210 return ret;195 return ret;
211 }196 }
212 197
213 if (vendor == 0x00) {198 if (vendor == 0x00) {
214 DRM_DEV_ERROR(acx->dev, "device vendor ID is zero\n");199 dev_err(acx->dev, "device vendor ID is zero\n");
215 return -ENODEV;200 return -ENODEV;
216 }201 }
217 202
@@ -220,14 +205,12 @@ static int acx424akp_read_id(struct acx424akp *acx) · 2 unmodified lines
220 case DISPLAY_SONY_ACX424AKP_ID1:205 case DISPLAY_SONY_ACX424AKP_ID1:
221 case DISPLAY_SONY_ACX424AKP_ID2:206 case DISPLAY_SONY_ACX424AKP_ID2:
222 case DISPLAY_SONY_ACX424AKP_ID3:207 case DISPLAY_SONY_ACX424AKP_ID3:
223 DRM_DEV_INFO(acx->dev,208 dev_info(acx->dev, "MTP vendor: %02x, version: %02x, panel: %02x\n",
224 "MTP vendor: %02x, version: %02x, panel: %02x\n",209 vendor, version, panel);
225 vendor, version, panel);
226 break;210 break;
227 default:211 default:
228 DRM_DEV_INFO(acx->dev,212 dev_info(acx->dev, "unknown vendor: %02x, version: %02x, panel: %02x\n",
229 "unknown vendor: %02x, version: %02x, panel: %02x\n",213 vendor, version, panel);
230 vendor, version, panel);
231 break;214 break;
232 }215 }
233 216
@@ -240,7 +223,7 @@ static int acx424akp_power_on(struct acx424akp *acx) · 6 unmodified lines
240 223
241 ret = regulator_enable(acx->supply);224 ret = regulator_enable(acx->supply);
242 if (ret) {225 if (ret) {
243 DRM_DEV_ERROR(acx->dev, "failed to enable supply (%d)\n", ret);226 dev_err(acx->dev, "failed to enable supply (%d)\n", ret);
244 return ret;227 return ret;
245 }228 }
246 229
@@ -276,7 +259,7 @@ static int acx424akp_prepare(struct drm_panel *panel) · 29 unmodified lines
276 259
277 ret = acx424akp_read_id(acx);260 ret = acx424akp_read_id(acx);
278 if (ret) {261 if (ret) {
279 DRM_DEV_ERROR(acx->dev, "failed to read panel ID (%d)\n", ret);262 dev_err(acx->dev, "failed to read panel ID (%d)\n", ret);
280 goto err_power_off;263 goto err_power_off;
281 }264 }
282 265
@@ -284,8 +267,7 @@ static int acx424akp_prepare(struct drm_panel *panel) · 1 unmodified line
284 ret = mipi_dsi_dcs_set_tear_on(dsi,267 ret = mipi_dsi_dcs_set_tear_on(dsi,
285 MIPI_DSI_DCS_TEAR_MODE_VBLANK);268 MIPI_DSI_DCS_TEAR_MODE_VBLANK);
286 if (ret) {269 if (ret) {
287 DRM_DEV_ERROR(acx->dev, "failed to enable vblank TE (%d)\n",270 dev_err(acx->dev, "failed to enable vblank TE (%d)\n", ret);
288 ret);
289 goto err_power_off;271 goto err_power_off;
290 }272 }
291 273
@@ -302,23 +284,21 @@ static int acx424akp_prepare(struct drm_panel *panel) · 10 unmodified lines
302 ret = mipi_dsi_dcs_write(dsi, ACX424_DCS_SET_MDDI,284 ret = mipi_dsi_dcs_write(dsi, ACX424_DCS_SET_MDDI,
303 &mddi, sizeof(mddi));285 &mddi, sizeof(mddi));
304 if (ret < 0) {286 if (ret < 0) {
305 DRM_DEV_ERROR(acx->dev, "failed to set MDDI (%d)\n", ret);287 dev_err(acx->dev, "failed to set MDDI (%d)\n", ret);
306 goto err_power_off;288 goto err_power_off;
307 }289 }
308 290
309 /* Exit sleep mode */291 /* Exit sleep mode */
310 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);292 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
311 if (ret) {293 if (ret) {
312 DRM_DEV_ERROR(acx->dev, "failed to exit sleep mode (%d)\n",294 dev_err(acx->dev, "failed to exit sleep mode (%d)\n", ret);
313 ret);
314 goto err_power_off;295 goto err_power_off;
315 }296 }
316 msleep(140);297 msleep(140);
317 298
318 ret = mipi_dsi_dcs_set_display_on(dsi);299 ret = mipi_dsi_dcs_set_display_on(dsi);
319 if (ret) {300 if (ret) {
320 DRM_DEV_ERROR(acx->dev, "failed to turn display on (%d)\n",301 dev_err(acx->dev, "failed to turn display on (%d)\n", ret);
321 ret);
322 goto err_power_off;302 goto err_power_off;
323 }303 }
324 if (acx->video_mode) {304 if (acx->video_mode) {
@@ -351,24 +331,20 @@ static int acx424akp_unprepare(struct drm_panel *panel) · 26 unmodified lines
351 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,331 ret = mipi_dsi_dcs_write(dsi, MIPI_DCS_WRITE_CONTROL_DISPLAY,
352 &par, 1);332 &par, 1);
353 if (ret) {333 if (ret) {
354 DRM_DEV_ERROR(acx->dev,334 dev_err(acx->dev, "failed to disable display backlight (%d)\n", ret);
355 "failed to disable display backlight (%d)\n",
356 ret);
357 return ret;335 return ret;
358 }336 }
359 337
360 ret = mipi_dsi_dcs_set_display_off(dsi);338 ret = mipi_dsi_dcs_set_display_off(dsi);
361 if (ret) {339 if (ret) {
362 DRM_DEV_ERROR(acx->dev, "failed to turn display off (%d)\n",340 dev_err(acx->dev, "failed to turn display off (%d)\n", ret);
363 ret);
364 return ret;341 return ret;
365 }342 }
366 343
367 /* Enter sleep mode */344 /* Enter sleep mode */
368 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);345 ret = mipi_dsi_dcs_enter_sleep_mode(dsi);
369 if (ret) {346 if (ret) {
370 DRM_DEV_ERROR(acx->dev, "failed to enter sleep mode (%d)\n",347 dev_err(acx->dev, "failed to enter sleep mode (%d)\n", ret);
371 ret);
372 return ret;348 return ret;
373 }349 }
374 msleep(85);350 msleep(85);
@@ -418,7 +394,7 @@ static int acx424akp_get_modes(struct drm_panel *panel, · 43 unmodified lines
418 mode = drm_mode_duplicate(connector->dev,394 mode = drm_mode_duplicate(connector->dev,
419 &sony_acx424akp_cmd_mode);395 &sony_acx424akp_cmd_mode);
420 if (!mode) {396 if (!mode) {
421 DRM_ERROR("bad mode or failed to add mode\n");397 dev_err(panel->dev, "bad mode or failed to add mode\n");
422 return -EINVAL;398 return -EINVAL;
423 }399 }
424 drm_mode_set_name(mode);400 drm_mode_set_name(mode);
@@ -486,8 +462,7 @@ static int acx424akp_probe(struct mipi_dsi_device *dsi) · 61 unmodified lines
486 if (IS_ERR(acx->reset_gpio)) {462 if (IS_ERR(acx->reset_gpio)) {
487 ret = PTR_ERR(acx->reset_gpio);463 ret = PTR_ERR(acx->reset_gpio);
488 if (ret != -EPROBE_DEFER)464 if (ret != -EPROBE_DEFER)
489 DRM_DEV_ERROR(dev, "failed to request GPIO (%d)\n",465 dev_err(dev, "failed to request GPIO (%d)\n", ret);
490 ret);
491 return ret;466 return ret;
492 }467 }
493 468
@@ -497,16 +472,14 @@ static int acx424akp_probe(struct mipi_dsi_device *dsi) · 3 unmodified lines
497 acx->bl = devm_backlight_device_register(dev, "acx424akp", dev, acx,472 acx->bl = devm_backlight_device_register(dev, "acx424akp", dev, acx,
498 &acx424akp_bl_ops, NULL);473 &acx424akp_bl_ops, NULL);
499 if (IS_ERR(acx->bl)) {474 if (IS_ERR(acx->bl)) {
500 DRM_DEV_ERROR(dev, "failed to register backlight device\n");475 dev_err(dev, "failed to register backlight device\n");
501 return PTR_ERR(acx->bl);476 return PTR_ERR(acx->bl);
502 }477 }
503 acx->bl->props.max_brightness = 1023;478 acx->bl->props.max_brightness = 1023;
504 acx->bl->props.brightness = 512;479 acx->bl->props.brightness = 512;
505 acx->bl->props.power = FB_BLANK_POWERDOWN;480 acx->bl->props.power = FB_BLANK_POWERDOWN;
506 481
507 ret = drm_panel_add(&acx->panel);482 drm_panel_add(&acx->panel);
508 if (ret < 0)
509 return ret;
510 483
511 ret = mipi_dsi_attach(dsi);484 ret = mipi_dsi_attach(dsi);
512 if (ret < 0) {485 if (ret < 0) {
drivers/gpu/drm/panel/panel-sony-acx565akm.c+1−6
@@ -650,12 +650,7 @@ static int acx565akm_probe(struct spi_device *spi) · 649 unmodified lines
650 drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs,650 drm_panel_init(&lcd->panel, &lcd->spi->dev, &acx565akm_funcs,
651 DRM_MODE_CONNECTOR_DPI);651 DRM_MODE_CONNECTOR_DPI);
652 652
653 ret = drm_panel_add(&lcd->panel);653 drm_panel_add(&lcd->panel);
654 if (ret < 0) {
655 if (lcd->has_bc)
656 acx565akm_backlight_cleanup(lcd);
657 return ret;
658 }
659 654
660 return 0;655 return 0;
661}656}
drivers/gpu/drm/panel/panel-tpo-td028ttec1.c+3−1
@@ -350,7 +350,9 @@ static int td028ttec1_probe(struct spi_device *spi) · 349 unmodified lines
350 if (ret)350 if (ret)
351 return ret;351 return ret;
352 352
353 return drm_panel_add(&lcd->panel);353 drm_panel_add(&lcd->panel);
354
355 return 0;
354}356}
355 357
356static int td028ttec1_remove(struct spi_device *spi)358static int td028ttec1_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-tpo-td043mtea1.c+1−5
@@ -460,11 +460,7 @@ static int td043mtea1_probe(struct spi_device *spi) · 459 unmodified lines
460 drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs,460 drm_panel_init(&lcd->panel, &lcd->spi->dev, &td043mtea1_funcs,
461 DRM_MODE_CONNECTOR_DPI);461 DRM_MODE_CONNECTOR_DPI);
462 462
463 ret = drm_panel_add(&lcd->panel);463 drm_panel_add(&lcd->panel);
464 if (ret < 0) {
465 sysfs_remove_group(&spi->dev.kobj, &td043mtea1_attr_group);
466 return ret;
467 }
468 464
469 return 0;465 return 0;
470}466}
drivers/gpu/drm/panel/panel-tpo-tpg110.c+20−22
@@ -12,7 +12,6 @@ · 11 unmodified lines
12 */12 */
13#include <drm/drm_modes.h>13#include <drm/drm_modes.h>
14#include <drm/drm_panel.h>14#include <drm/drm_panel.h>
15#include <drm/drm_print.h>
16 15
17#include <linux/bitops.h>16#include <linux/bitops.h>
18#include <linux/delay.h>17#include <linux/delay.h>
@@ -238,7 +237,7 @@ static u8 tpg110_readwrite_reg(struct tpg110 *tpg, bool write, · 219 unmodified lines
238 spi_message_add_tail(&t[1], &m);237 spi_message_add_tail(&t[1], &m);
239 ret = spi_sync(tpg->spi, &m);238 ret = spi_sync(tpg->spi, &m);
240 if (ret) {239 if (ret) {
241 DRM_DEV_ERROR(tpg->dev, "SPI message error %d\n", ret);240 dev_err(tpg->dev, "SPI message error %d\n", ret);
242 return ret;241 return ret;
243 }242 }
244 if (write)243 if (write)
@@ -265,18 +264,18 @@ static int tpg110_startup(struct tpg110 *tpg) · 20 unmodified lines
265 /* De-assert the reset signal */264 /* De-assert the reset signal */
266 gpiod_set_value_cansleep(tpg->grestb, 0);265 gpiod_set_value_cansleep(tpg->grestb, 0);
267 usleep_range(1000, 2000);266 usleep_range(1000, 2000);
268 DRM_DEV_DEBUG(tpg->dev, "de-asserted GRESTB\n");267 dev_dbg(tpg->dev, "de-asserted GRESTB\n");
269 268
270 /* Test display communication */269 /* Test display communication */
271 tpg110_write_reg(tpg, TPG110_TEST, 0x55);270 tpg110_write_reg(tpg, TPG110_TEST, 0x55);
272 val = tpg110_read_reg(tpg, TPG110_TEST);271 val = tpg110_read_reg(tpg, TPG110_TEST);
273 if (val != 0x55) {272 if (val != 0x55) {
274 DRM_DEV_ERROR(tpg->dev, "failed communication test\n");273 dev_err(tpg->dev, "failed communication test\n");
275 return -ENODEV;274 return -ENODEV;
276 }275 }
277 276
278 val = tpg110_read_reg(tpg, TPG110_CHIPID);277 val = tpg110_read_reg(tpg, TPG110_CHIPID);
279 DRM_DEV_INFO(tpg->dev, "TPG110 chip ID: %d version: %d\n",278 dev_info(tpg->dev, "TPG110 chip ID: %d version: %d\n",
280 val >> 4, val & 0x0f);279 val >> 4, val & 0x0f);
281 280
282 /* Show display resolution */281 /* Show display resolution */
@@ -284,27 +283,25 @@ static int tpg110_startup(struct tpg110 *tpg) · 1 unmodified line
284 val &= TPG110_RES_MASK;283 val &= TPG110_RES_MASK;
285 switch (val) {284 switch (val) {
286 case TPG110_RES_400X240_D:285 case TPG110_RES_400X240_D:
287 DRM_DEV_INFO(tpg->dev,286 dev_info(tpg->dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n");
288 "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n");
289 break;287 break;
290 case TPG110_RES_480X272_D:288 case TPG110_RES_480X272_D:
291 DRM_DEV_INFO(tpg->dev,289 dev_info(tpg->dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n");
292 "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n");
293 break;290 break;
294 case TPG110_RES_480X640:291 case TPG110_RES_480X640:
295 DRM_DEV_INFO(tpg->dev, "480x640 RGB\n");292 dev_info(tpg->dev, "480x640 RGB\n");
296 break;293 break;
297 case TPG110_RES_480X272:294 case TPG110_RES_480X272:
298 DRM_DEV_INFO(tpg->dev, "480x272 RGB\n");295 dev_info(tpg->dev, "480x272 RGB\n");
299 break;296 break;
300 case TPG110_RES_640X480:297 case TPG110_RES_640X480:
301 DRM_DEV_INFO(tpg->dev, "640x480 RGB\n");298 dev_info(tpg->dev, "640x480 RGB\n");
302 break;299 break;
303 case TPG110_RES_800X480:300 case TPG110_RES_800X480:
304 DRM_DEV_INFO(tpg->dev, "800x480 RGB\n");301 dev_info(tpg->dev, "800x480 RGB\n");
305 break;302 break;
306 default:303 default:
307 DRM_DEV_ERROR(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val);304 dev_err(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val);
308 break;305 break;
309 }306 }
310 307
@@ -322,13 +319,12 @@ static int tpg110_startup(struct tpg110 *tpg) · 11 unmodified lines
322 }319 }
323 }320 }
324 if (i == ARRAY_SIZE(tpg110_modes)) {321 if (i == ARRAY_SIZE(tpg110_modes)) {
325 DRM_DEV_ERROR(tpg->dev, "unsupported mode (%02x) detected\n",322 dev_err(tpg->dev, "unsupported mode (%02x) detected\n", val);
326 val);
327 return -ENODEV;323 return -ENODEV;
328 }324 }
329 325
330 val = tpg110_read_reg(tpg, TPG110_CTRL2);326 val = tpg110_read_reg(tpg, TPG110_CTRL2);
331 DRM_DEV_INFO(tpg->dev, "resolution and standby is controlled by %s\n",327 dev_info(tpg->dev, "resolution and standby is controlled by %s\n",
332 (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware");328 (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware");
333 /* Take control over resolution and standby */329 /* Take control over resolution and standby */
334 val |= TPG110_CTRL2_RES_PM_CTRL;330 val |= TPG110_CTRL2_RES_PM_CTRL;
@@ -414,15 +410,15 @@ static int tpg110_probe(struct spi_device *spi) · 79 unmodified lines
414 /* We get the physical display dimensions from the DT */410 /* We get the physical display dimensions from the DT */
415 ret = of_property_read_u32(np, "width-mm", &tpg->width);411 ret = of_property_read_u32(np, "width-mm", &tpg->width);
416 if (ret)412 if (ret)
417 DRM_DEV_ERROR(dev, "no panel width specified\n");413 dev_err(dev, "no panel width specified\n");
418 ret = of_property_read_u32(np, "height-mm", &tpg->height);414 ret = of_property_read_u32(np, "height-mm", &tpg->height);
419 if (ret)415 if (ret)
420 DRM_DEV_ERROR(dev, "no panel height specified\n");416 dev_err(dev, "no panel height specified\n");
421 417
422 /* This asserts the GRESTB signal, putting the display into reset */418 /* This asserts the GRESTB signal, putting the display into reset */
423 tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH);419 tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH);
424 if (IS_ERR(tpg->grestb)) {420 if (IS_ERR(tpg->grestb)) {
425 DRM_DEV_ERROR(dev, "no GRESTB GPIO\n");421 dev_err(dev, "no GRESTB GPIO\n");
426 return -ENODEV;422 return -ENODEV;
427 }423 }
428 424
@@ -430,7 +426,7 @@ static int tpg110_probe(struct spi_device *spi) · 1 unmodified line
430 spi->mode |= SPI_3WIRE_HIZ;426 spi->mode |= SPI_3WIRE_HIZ;
431 ret = spi_setup(spi);427 ret = spi_setup(spi);
432 if (ret < 0) {428 if (ret < 0) {
433 DRM_DEV_ERROR(dev, "spi setup failed.\n");429 dev_err(dev, "spi setup failed.\n");
434 return ret;430 return ret;
435 }431 }
436 tpg->spi = spi;432 tpg->spi = spi;
@@ -448,7 +444,9 @@ static int tpg110_probe(struct spi_device *spi) · 11 unmodified lines
448 444
449 spi_set_drvdata(spi, tpg);445 spi_set_drvdata(spi, tpg);
450 446
451 return drm_panel_add(&tpg->panel);447 drm_panel_add(&tpg->panel);
448
449 return 0;
452}450}
453 451
454static int tpg110_remove(struct spi_device *spi)452static int tpg110_remove(struct spi_device *spi)
drivers/gpu/drm/panel/panel-truly-nt35597.c+21−42
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <drm/drm_mipi_dsi.h>17#include <drm/drm_mipi_dsi.h>
18#include <drm/drm_modes.h>18#include <drm/drm_modes.h>
19#include <drm/drm_panel.h>19#include <drm/drm_panel.h>
20#include <drm/drm_print.h>
21 20
22static const char * const regulator_names[] = {21static const char * const regulator_names[] = {
23 "vdda",22 "vdda",
@@ -231,9 +230,7 @@ static int truly_dcs_write(struct drm_panel *panel, u32 command) · 207 unmodified lines
231 for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {230 for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
232 ret = mipi_dsi_dcs_write(ctx->dsi[i], command, NULL, 0);231 ret = mipi_dsi_dcs_write(ctx->dsi[i], command, NULL, 0);
233 if (ret < 0) {232 if (ret < 0) {
234 DRM_DEV_ERROR(ctx->dev,233 dev_err(ctx->dev, "cmd 0x%x failed for dsi = %d\n", command, i);
235 "cmd 0x%x failed for dsi = %d\n",
236 command, i);
237 }234 }
238 }235 }
239 236
@@ -250,8 +247,7 @@ static int truly_dcs_write_buf(struct drm_panel *panel, · 10 unmodified lines
250 for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {247 for (i = 0; i < ARRAY_SIZE(ctx->dsi); i++) {
251 ret = mipi_dsi_dcs_write_buffer(ctx->dsi[i], buf, size);248 ret = mipi_dsi_dcs_write_buffer(ctx->dsi[i], buf, size);
252 if (ret < 0) {249 if (ret < 0) {
253 DRM_DEV_ERROR(ctx->dev,250 dev_err(ctx->dev, "failed to tx cmd [%d], err: %d\n", i, ret);
254 "failed to tx cmd [%d], err: %d\n", i, ret);
255 return ret;251 return ret;
256 }252 }
257 }253 }
@@ -300,16 +296,14 @@ static int truly_nt35597_power_off(struct truly_nt35597 *ctx) · 42 unmodified lines
300 ret = regulator_set_load(ctx->supplies[i].consumer,296 ret = regulator_set_load(ctx->supplies[i].consumer,
301 regulator_disable_loads[i]);297 regulator_disable_loads[i]);
302 if (ret) {298 if (ret) {
303 DRM_DEV_ERROR(ctx->dev,299 dev_err(ctx->dev, "regulator_set_load failed %d\n", ret);
304 "regulator_set_load failed %d\n", ret);
305 return ret;300 return ret;
306 }301 }
307 }302 }
308 303
309 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);304 ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
310 if (ret) {305 if (ret) {
311 DRM_DEV_ERROR(ctx->dev,306 dev_err(ctx->dev, "regulator_bulk_disable failed %d\n", ret);
312 "regulator_bulk_disable failed %d\n", ret);
313 }307 }
314 return ret;308 return ret;
315}309}
@@ -325,8 +319,7 @@ static int truly_nt35597_disable(struct drm_panel *panel) · 9 unmodified lines
325 if (ctx->backlight) {319 if (ctx->backlight) {
326 ret = backlight_disable(ctx->backlight);320 ret = backlight_disable(ctx->backlight);
327 if (ret < 0)321 if (ret < 0)
328 DRM_DEV_ERROR(ctx->dev, "backlight disable failed %d\n",322 dev_err(ctx->dev, "backlight disable failed %d\n", ret);
329 ret);
330 }323 }
331 324
332 ctx->enabled = false;325 ctx->enabled = false;
@@ -346,9 +339,7 @@ static int truly_nt35597_unprepare(struct drm_panel *panel) · 13 unmodified lines
346 339
347 ret = truly_dcs_write(panel, MIPI_DCS_SET_DISPLAY_OFF);340 ret = truly_dcs_write(panel, MIPI_DCS_SET_DISPLAY_OFF);
348 if (ret < 0) {341 if (ret < 0) {
349 DRM_DEV_ERROR(ctx->dev,342 dev_err(ctx->dev, "set_display_off cmd failed ret = %d\n", ret);
350 "set_display_off cmd failed ret = %d\n",
351 ret);
352 }343 }
353 344
354 /* 120ms delay required here as per DCS spec */345 /* 120ms delay required here as per DCS spec */
@@ -356,13 +347,12 @@ static int truly_nt35597_unprepare(struct drm_panel *panel) · 1 unmodified line
356 347
357 ret = truly_dcs_write(panel, MIPI_DCS_ENTER_SLEEP_MODE);348 ret = truly_dcs_write(panel, MIPI_DCS_ENTER_SLEEP_MODE);
358 if (ret < 0) {349 if (ret < 0) {
359 DRM_DEV_ERROR(ctx->dev,350 dev_err(ctx->dev, "enter_sleep cmd failed ret = %d\n", ret);
360 "enter_sleep cmd failed ret = %d\n", ret);
361 }351 }
362 352
363 ret = truly_nt35597_power_off(ctx);353 ret = truly_nt35597_power_off(ctx);
364 if (ret < 0)354 if (ret < 0)
365 DRM_DEV_ERROR(ctx->dev, "power_off failed ret = %d\n", ret);355 dev_err(ctx->dev, "power_off failed ret = %d\n", ret);
366 356
367 ctx->prepared = false;357 ctx->prepared = false;
368 return ret;358 return ret;
@@ -396,18 +386,14 @@ static int truly_nt35597_prepare(struct drm_panel *panel) · 27 unmodified lines
396 panel_on_cmds[i].size,386 panel_on_cmds[i].size,
397 panel_on_cmds[i].commands);387 panel_on_cmds[i].commands);
398 if (ret < 0) {388 if (ret < 0) {
399 DRM_DEV_ERROR(ctx->dev,389 dev_err(ctx->dev, "cmd set tx failed i = %d ret = %d\n", i, ret);
400 "cmd set tx failed i = %d ret = %d\n",
401 i, ret);
402 goto power_off;390 goto power_off;
403 }391 }
404 }392 }
405 393
406 ret = truly_dcs_write(panel, MIPI_DCS_EXIT_SLEEP_MODE);394 ret = truly_dcs_write(panel, MIPI_DCS_EXIT_SLEEP_MODE);
407 if (ret < 0) {395 if (ret < 0) {
408 DRM_DEV_ERROR(ctx->dev,396 dev_err(ctx->dev, "exit_sleep_mode cmd failed ret = %d\n", ret);
409 "exit_sleep_mode cmd failed ret = %d\n",
410 ret);
411 goto power_off;397 goto power_off;
412 }398 }
413 399
@@ -416,8 +402,7 @@ static int truly_nt35597_prepare(struct drm_panel *panel) · 2 unmodified lines
416 402
417 ret = truly_dcs_write(panel, MIPI_DCS_SET_DISPLAY_ON);403 ret = truly_dcs_write(panel, MIPI_DCS_SET_DISPLAY_ON);
418 if (ret < 0) {404 if (ret < 0) {
419 DRM_DEV_ERROR(ctx->dev,405 dev_err(ctx->dev, "set_display_on cmd failed ret = %d\n", ret);
420 "set_display_on cmd failed ret = %d\n", ret);
421 goto power_off;406 goto power_off;
422 }407 }
423 408
@@ -430,7 +415,7 @@ static int truly_nt35597_prepare(struct drm_panel *panel) · 6 unmodified lines
430 415
431power_off:416power_off:
432 if (truly_nt35597_power_off(ctx))417 if (truly_nt35597_power_off(ctx))
433 DRM_DEV_ERROR(ctx->dev, "power_off failed\n");418 dev_err(ctx->dev, "power_off failed\n");
434 return ret;419 return ret;
435}420}
436 421
@@ -445,8 +430,7 @@ static int truly_nt35597_enable(struct drm_panel *panel) · 8 unmodified lines
445 if (ctx->backlight) {430 if (ctx->backlight) {
446 ret = backlight_enable(ctx->backlight);431 ret = backlight_enable(ctx->backlight);
447 if (ret < 0)432 if (ret < 0)
448 DRM_DEV_ERROR(ctx->dev, "backlight enable failed %d\n",433 dev_err(ctx->dev, "backlight enable failed %d\n", ret);
449 ret);
450 }434 }
451 435
452 ctx->enabled = true;436 ctx->enabled = true;
@@ -464,8 +448,7 @@ static int truly_nt35597_get_modes(struct drm_panel *panel, · 11 unmodified lines
464 config = ctx->config;448 config = ctx->config;
465 mode = drm_mode_create(connector->dev);449 mode = drm_mode_create(connector->dev);
466 if (!mode) {450 if (!mode) {
467 DRM_DEV_ERROR(ctx->dev,451 dev_err(ctx->dev, "failed to create a new display mode\n");
468 "failed to create a new display mode\n");
469 return 0;452 return 0;
470 }453 }
471 454
@@ -501,15 +484,13 @@ static int truly_nt35597_panel_add(struct truly_nt35597 *ctx) · 29 unmodified lines
501 484
502 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);485 ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
503 if (IS_ERR(ctx->reset_gpio)) {486 if (IS_ERR(ctx->reset_gpio)) {
504 DRM_DEV_ERROR(dev, "cannot get reset gpio %ld\n",487 dev_err(dev, "cannot get reset gpio %ld\n", PTR_ERR(ctx->reset_gpio));
505 PTR_ERR(ctx->reset_gpio));
506 return PTR_ERR(ctx->reset_gpio);488 return PTR_ERR(ctx->reset_gpio);
507 }489 }
508 490
509 ctx->mode_gpio = devm_gpiod_get(dev, "mode", GPIOD_OUT_LOW);491 ctx->mode_gpio = devm_gpiod_get(dev, "mode", GPIOD_OUT_LOW);
510 if (IS_ERR(ctx->mode_gpio)) {492 if (IS_ERR(ctx->mode_gpio)) {
511 DRM_DEV_ERROR(dev, "cannot get mode gpio %ld\n",493 dev_err(dev, "cannot get mode gpio %ld\n", PTR_ERR(ctx->mode_gpio));
512 PTR_ERR(ctx->mode_gpio));
513 return PTR_ERR(ctx->mode_gpio);494 return PTR_ERR(ctx->mode_gpio);
514 }495 }
515 496
@@ -584,22 +565,21 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi) · 68 unmodified lines
584 565
585 dsi1 = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);566 dsi1 = of_graph_get_remote_node(dsi->dev.of_node, 1, -1);
586 if (!dsi1) {567 if (!dsi1) {
587 DRM_DEV_ERROR(dev,568 dev_err(dev, "failed to get remote node for dsi1_device\n");
588 "failed to get remote node for dsi1_device\n");
589 return -ENODEV;569 return -ENODEV;
590 }570 }
591 571
592 dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);572 dsi1_host = of_find_mipi_dsi_host_by_node(dsi1);
593 of_node_put(dsi1);573 of_node_put(dsi1);
594 if (!dsi1_host) {574 if (!dsi1_host) {
595 DRM_DEV_ERROR(dev, "failed to find dsi host\n");575 dev_err(dev, "failed to find dsi host\n");
596 return -EPROBE_DEFER;576 return -EPROBE_DEFER;
597 }577 }
598 578
599 /* register the second DSI device */579 /* register the second DSI device */
600 dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);580 dsi1_device = mipi_dsi_device_register_full(dsi1_host, &info);
601 if (IS_ERR(dsi1_device)) {581 if (IS_ERR(dsi1_device)) {
602 DRM_DEV_ERROR(dev, "failed to create dsi device\n");582 dev_err(dev, "failed to create dsi device\n");
603 return PTR_ERR(dsi1_device);583 return PTR_ERR(dsi1_device);
604 }584 }
605 585
@@ -611,7 +591,7 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi) · 5 unmodified lines
611 591
612 ret = truly_nt35597_panel_add(ctx);592 ret = truly_nt35597_panel_add(ctx);
613 if (ret) {593 if (ret) {
614 DRM_DEV_ERROR(dev, "failed to add panel\n");594 dev_err(dev, "failed to add panel\n");
615 goto err_panel_add;595 goto err_panel_add;
616 }596 }
617 597
@@ -623,8 +603,7 @@ static int truly_nt35597_probe(struct mipi_dsi_device *dsi) · 5 unmodified lines
623 MIPI_DSI_CLOCK_NON_CONTINUOUS;603 MIPI_DSI_CLOCK_NON_CONTINUOUS;
624 ret = mipi_dsi_attach(dsi_dev);604 ret = mipi_dsi_attach(dsi_dev);
625 if (ret < 0) {605 if (ret < 0) {
626 DRM_DEV_ERROR(dev,606 dev_err(dev, "dsi attach failed i = %d\n", i);
627 "dsi attach failed i = %d\n", i);
628 goto err_dsi_attach;607 goto err_dsi_attach;
629 }608 }
630 }609 }
drivers/gpu/drm/panel/panel-visionox-rm69299.c+13−28
@@ -14,7 +14,6 @@ · 13 unmodified lines
14#include <drm/drm_mipi_dsi.h>14#include <drm/drm_mipi_dsi.h>
15#include <drm/drm_modes.h>15#include <drm/drm_modes.h>
16#include <drm/drm_panel.h>16#include <drm/drm_panel.h>
17#include <drm/drm_print.h>
18 17
19struct visionox_rm69299 {18struct visionox_rm69299 {
20 struct drm_panel panel;19 struct drm_panel panel;
@@ -69,16 +68,14 @@ static int visionox_rm69299_unprepare(struct drm_panel *panel) · 48 unmodified lines
69 68
70 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);69 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
71 if (ret < 0)70 if (ret < 0)
72 DRM_DEV_ERROR(ctx->panel.dev,71 dev_err(ctx->panel.dev, "set_display_off cmd failed ret = %d\n", ret);
73 "set_display_off cmd failed ret = %d\n", ret);
74 72
75 /* 120ms delay required here as per DCS spec */73 /* 120ms delay required here as per DCS spec */
76 msleep(120);74 msleep(120);
77 75
78 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);76 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
79 if (ret < 0) {77 if (ret < 0) {
80 DRM_DEV_ERROR(ctx->panel.dev,78 dev_err(ctx->panel.dev, "enter_sleep cmd failed ret = %d\n", ret);
81 "enter_sleep cmd failed ret = %d\n", ret);
82 }79 }
83 80
84 ret = visionox_rm69299_power_off(ctx);81 ret = visionox_rm69299_power_off(ctx);
@@ -103,36 +100,31 @@ static int visionox_rm69299_prepare(struct drm_panel *panel) · 18 unmodified lines
103 100
104 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xfe, 0x00 }, 2);101 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xfe, 0x00 }, 2);
105 if (ret < 0) {102 if (ret < 0) {
106 DRM_DEV_ERROR(ctx->panel.dev,103 dev_err(ctx->panel.dev, "cmd set tx 0 failed, ret = %d\n", ret);
107 "cmd set tx 0 failed, ret = %d\n", ret);
108 goto power_off;104 goto power_off;
109 }105 }
110 106
111 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xc2, 0x08 }, 2);107 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0xc2, 0x08 }, 2);
112 if (ret < 0) {108 if (ret < 0) {
113 DRM_DEV_ERROR(ctx->panel.dev,109 dev_err(ctx->panel.dev, "cmd set tx 1 failed, ret = %d\n", ret);
114 "cmd set tx 1 failed, ret = %d\n", ret);
115 goto power_off;110 goto power_off;
116 }111 }
117 112
118 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x35, 0x00 }, 2);113 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x35, 0x00 }, 2);
119 if (ret < 0) {114 if (ret < 0) {
120 DRM_DEV_ERROR(ctx->panel.dev,115 dev_err(ctx->panel.dev, "cmd set tx 2 failed, ret = %d\n", ret);
121 "cmd set tx 2 failed, ret = %d\n", ret);
122 goto power_off;116 goto power_off;
123 }117 }
124 118
125 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x51, 0xff }, 2);119 ret = mipi_dsi_dcs_write_buffer(ctx->dsi, (u8[]) { 0x51, 0xff }, 2);
126 if (ret < 0) {120 if (ret < 0) {
127 DRM_DEV_ERROR(ctx->panel.dev,121 dev_err(ctx->panel.dev, "cmd set tx 3 failed, ret = %d\n", ret);
128 "cmd set tx 3 failed, ret = %d\n", ret);
129 goto power_off;122 goto power_off;
130 }123 }
131 124
132 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);125 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
133 if (ret < 0) {126 if (ret < 0) {
134 DRM_DEV_ERROR(ctx->panel.dev,127 dev_err(ctx->panel.dev, "exit_sleep_mode cmd failed ret = %d\n", ret);
135 "exit_sleep_mode cmd failed ret = %d\n", ret);
136 goto power_off;128 goto power_off;
137 }129 }
138 130
@@ -141,8 +133,7 @@ static int visionox_rm69299_prepare(struct drm_panel *panel) · 2 unmodified lines
141 133
142 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);134 ret = mipi_dsi_dcs_write(ctx->dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
143 if (ret < 0) {135 if (ret < 0) {
144 DRM_DEV_ERROR(ctx->panel.dev,136 dev_err(ctx->panel.dev, "set_display_on cmd failed ret = %d\n", ret);
145 "set_display_on cmd failed ret = %d\n", ret);
146 goto power_off;137 goto power_off;
147 }138 }
148 139
@@ -179,8 +170,7 @@ static int visionox_rm69299_get_modes(struct drm_panel *panel, · 30 unmodified lines
179 170
180 mode = drm_mode_create(connector->dev);171 mode = drm_mode_create(connector->dev);
181 if (!mode) {172 if (!mode) {
182 DRM_DEV_ERROR(ctx->panel.dev,173 dev_err(ctx->panel.dev, "failed to create a new display mode\n");
183 "failed to create a new display mode\n");
184 return 0;174 return 0;
185 }175 }
186 176
@@ -225,8 +215,7 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) · 38 unmodified lines
225 ctx->reset_gpio = devm_gpiod_get(ctx->panel.dev,215 ctx->reset_gpio = devm_gpiod_get(ctx->panel.dev,
226 "reset", GPIOD_OUT_LOW);216 "reset", GPIOD_OUT_LOW);
227 if (IS_ERR(ctx->reset_gpio)) {217 if (IS_ERR(ctx->reset_gpio)) {
228 DRM_DEV_ERROR(dev, "cannot get reset gpio %ld\n",218 dev_err(dev, "cannot get reset gpio %ld\n", PTR_ERR(ctx->reset_gpio));
229 PTR_ERR(ctx->reset_gpio));
230 return PTR_ERR(ctx->reset_gpio);219 return PTR_ERR(ctx->reset_gpio);
231 }220 }
232 221
@@ -242,23 +231,19 @@ static int visionox_rm69299_probe(struct mipi_dsi_device *dsi) · 9 unmodified lines
242 MIPI_DSI_CLOCK_NON_CONTINUOUS;231 MIPI_DSI_CLOCK_NON_CONTINUOUS;
243 ret = mipi_dsi_attach(dsi);232 ret = mipi_dsi_attach(dsi);
244 if (ret < 0) {233 if (ret < 0) {
245 DRM_DEV_ERROR(dev, "dsi attach failed ret = %d\n", ret);234 dev_err(dev, "dsi attach failed ret = %d\n", ret);
246 goto err_dsi_attach;235 goto err_dsi_attach;
247 }236 }
248 237
249 ret = regulator_set_load(ctx->supplies[0].consumer, 32000);238 ret = regulator_set_load(ctx->supplies[0].consumer, 32000);
250 if (ret) {239 if (ret) {
251 DRM_DEV_ERROR(dev,240 dev_err(dev, "regulator set load failed for vdda supply ret = %d\n", ret);
252 "regulator set load failed for vdda supply ret = %d\n",
253 ret);
254 goto err_set_load;241 goto err_set_load;
255 }242 }
256 243
257 ret = regulator_set_load(ctx->supplies[1].consumer, 13200);244 ret = regulator_set_load(ctx->supplies[1].consumer, 13200);
258 if (ret) {245 if (ret) {
259 DRM_DEV_ERROR(dev,246 dev_err(dev, "regulator set load failed for vdd3p3 supply ret = %d\n", ret);
260 "regulator set load failed for vdd3p3 supply ret = %d\n",
261 ret);
262 goto err_set_load;247 goto err_set_load;
263 }248 }
264 249
drivers/gpu/drm/panel/panel-xinpeng-xpp055c272.c+19−32
@@ -12,7 +12,6 @@ · 11 unmodified lines
12#include <drm/drm_mipi_dsi.h>12#include <drm/drm_mipi_dsi.h>
13#include <drm/drm_modes.h>13#include <drm/drm_modes.h>
14#include <drm/drm_panel.h>14#include <drm/drm_panel.h>
15#include <drm/drm_print.h>
16 15
17#include <video/display_timing.h>16#include <video/display_timing.h>
18#include <video/mipi_display.h>17#include <video/mipi_display.h>
@@ -135,7 +134,7 @@ static int xpp055c272_init_sequence(struct xpp055c272 *ctx) · 116 unmodified lines
135 134
136 msleep(60);135 msleep(60);
137 136
138 DRM_DEV_DEBUG_DRIVER(dev, "Panel init sequence done\n");137 dev_dbg(dev, "Panel init sequence done\n");
139 return 0;138 return 0;
140}139}
141 140
@@ -150,13 +149,11 @@ static int xpp055c272_unprepare(struct drm_panel *panel) · 8 unmodified lines
150 149
151 ret = mipi_dsi_dcs_set_display_off(dsi);150 ret = mipi_dsi_dcs_set_display_off(dsi);
152 if (ret < 0)151 if (ret < 0)
153 DRM_DEV_ERROR(ctx->dev, "failed to set display off: %d\n",152 dev_err(ctx->dev, "failed to set display off: %d\n", ret);
154 ret);
155 153
156 mipi_dsi_dcs_enter_sleep_mode(dsi);154 mipi_dsi_dcs_enter_sleep_mode(dsi);
157 if (ret < 0) {155 if (ret < 0) {
158 DRM_DEV_ERROR(ctx->dev, "failed to enter sleep mode: %d\n",156 dev_err(ctx->dev, "failed to enter sleep mode: %d\n", ret);
159 ret);
160 return ret;157 return ret;
161 }158 }
162 159
@@ -177,17 +174,15 @@ static int xpp055c272_prepare(struct drm_panel *panel) · 14 unmodified lines
177 if (ctx->prepared)174 if (ctx->prepared)
178 return 0;175 return 0;
179 176
180 DRM_DEV_DEBUG_DRIVER(ctx->dev, "Resetting the panel\n");177 dev_dbg(ctx->dev, "Resetting the panel\n");
181 ret = regulator_enable(ctx->vci);178 ret = regulator_enable(ctx->vci);
182 if (ret < 0) {179 if (ret < 0) {
183 DRM_DEV_ERROR(ctx->dev,180 dev_err(ctx->dev, "Failed to enable vci supply: %d\n", ret);
184 "Failed to enable vci supply: %d\n", ret);
185 return ret;181 return ret;
186 }182 }
187 ret = regulator_enable(ctx->iovcc);183 ret = regulator_enable(ctx->iovcc);
188 if (ret < 0) {184 if (ret < 0) {
189 DRM_DEV_ERROR(ctx->dev,185 dev_err(ctx->dev, "Failed to enable iovcc supply: %d\n", ret);
190 "Failed to enable iovcc supply: %d\n", ret);
191 goto disable_vci;186 goto disable_vci;
192 }187 }
193 188
@@ -201,14 +196,13 @@ static int xpp055c272_prepare(struct drm_panel *panel) · 7 unmodified lines
201 196
202 ret = xpp055c272_init_sequence(ctx);197 ret = xpp055c272_init_sequence(ctx);
203 if (ret < 0) {198 if (ret < 0) {
204 DRM_DEV_ERROR(ctx->dev, "Panel init sequence failed: %d\n",199 dev_err(ctx->dev, "Panel init sequence failed: %d\n", ret);
205 ret);
206 goto disable_iovcc;200 goto disable_iovcc;
207 }201 }
208 202
209 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);203 ret = mipi_dsi_dcs_exit_sleep_mode(dsi);
210 if (ret < 0) {204 if (ret < 0) {
211 DRM_DEV_ERROR(ctx->dev, "Failed to exit sleep mode: %d\n", ret);205 dev_err(ctx->dev, "Failed to exit sleep mode: %d\n", ret);
212 goto disable_iovcc;206 goto disable_iovcc;
213 }207 }
214 208
@@ -217,7 +211,7 @@ static int xpp055c272_prepare(struct drm_panel *panel) · 2 unmodified lines
217 211
218 ret = mipi_dsi_dcs_set_display_on(dsi);212 ret = mipi_dsi_dcs_set_display_on(dsi);
219 if (ret < 0) {213 if (ret < 0) {
220 DRM_DEV_ERROR(ctx->dev, "Failed to set display on: %d\n", ret);214 dev_err(ctx->dev, "Failed to set display on: %d\n", ret);
221 goto disable_iovcc;215 goto disable_iovcc;
222 }216 }
223 217
@@ -256,9 +250,9 @@ static int xpp055c272_get_modes(struct drm_panel *panel, · 32 unmodified lines
256 250
257 mode = drm_mode_duplicate(connector->dev, &default_mode);251 mode = drm_mode_duplicate(connector->dev, &default_mode);
258 if (!mode) {252 if (!mode) {
259 DRM_DEV_ERROR(ctx->dev, "Failed to add mode %ux%u@%u\n",253 dev_err(ctx->dev, "Failed to add mode %ux%u@%u\n",
260 default_mode.hdisplay, default_mode.vdisplay,254 default_mode.hdisplay, default_mode.vdisplay,
261 drm_mode_vrefresh(&default_mode));255 drm_mode_vrefresh(&default_mode));
262 return -ENOMEM;256 return -ENOMEM;
263 }257 }
264 258
@@ -290,7 +284,7 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) · 25 unmodified lines
290 284
291 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);285 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
292 if (IS_ERR(ctx->reset_gpio)) {286 if (IS_ERR(ctx->reset_gpio)) {
293 DRM_DEV_ERROR(dev, "cannot get reset gpio\n");287 dev_err(dev, "cannot get reset gpio\n");
294 return PTR_ERR(ctx->reset_gpio);288 return PTR_ERR(ctx->reset_gpio);
295 }289 }
296 290
@@ -298,9 +292,7 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
298 if (IS_ERR(ctx->vci)) {292 if (IS_ERR(ctx->vci)) {
299 ret = PTR_ERR(ctx->vci);293 ret = PTR_ERR(ctx->vci);
300 if (ret != -EPROBE_DEFER)294 if (ret != -EPROBE_DEFER)
301 DRM_DEV_ERROR(dev,295 dev_err(dev, "Failed to request vci regulator: %d\n", ret);
302 "Failed to request vci regulator: %d\n",
303 ret);
304 return ret;296 return ret;
305 }297 }
306 298
@@ -308,9 +300,7 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) · 1 unmodified line
308 if (IS_ERR(ctx->iovcc)) {300 if (IS_ERR(ctx->iovcc)) {
309 ret = PTR_ERR(ctx->iovcc);301 ret = PTR_ERR(ctx->iovcc);
310 if (ret != -EPROBE_DEFER)302 if (ret != -EPROBE_DEFER)
311 DRM_DEV_ERROR(dev,303 dev_err(dev, "Failed to request iovcc regulator: %d\n", ret);
312 "Failed to request iovcc regulator: %d\n",
313 ret);
314 return ret;304 return ret;
315 }305 }
316 306
@@ -334,7 +324,7 @@ static int xpp055c272_probe(struct mipi_dsi_device *dsi) · 17 unmodified lines
334 324
335 ret = mipi_dsi_attach(dsi);325 ret = mipi_dsi_attach(dsi);
336 if (ret < 0) {326 if (ret < 0) {
337 DRM_DEV_ERROR(dev, "mipi_dsi_attach failed: %d\n", ret);327 dev_err(dev, "mipi_dsi_attach failed: %d\n", ret);
338 drm_panel_remove(&ctx->panel);328 drm_panel_remove(&ctx->panel);
339 return ret;329 return ret;
340 }330 }
@@ -349,13 +339,11 @@ static void xpp055c272_shutdown(struct mipi_dsi_device *dsi) · 8 unmodified lines
349 339
350 ret = drm_panel_unprepare(&ctx->panel);340 ret = drm_panel_unprepare(&ctx->panel);
351 if (ret < 0)341 if (ret < 0)
352 DRM_DEV_ERROR(&dsi->dev, "Failed to unprepare panel: %d\n",342 dev_err(&dsi->dev, "Failed to unprepare panel: %d\n", ret);
353 ret);
354 343
355 ret = drm_panel_disable(&ctx->panel);344 ret = drm_panel_disable(&ctx->panel);
356 if (ret < 0)345 if (ret < 0)
357 DRM_DEV_ERROR(&dsi->dev, "Failed to disable panel: %d\n",346 dev_err(&dsi->dev, "Failed to disable panel: %d\n", ret);
358 ret);
359}347}
360 348
361static int xpp055c272_remove(struct mipi_dsi_device *dsi)349static int xpp055c272_remove(struct mipi_dsi_device *dsi)
@@ -367,8 +355,7 @@ static int xpp055c272_remove(struct mipi_dsi_device *dsi) · 5 unmodified lines
367 355
368 ret = mipi_dsi_detach(dsi);356 ret = mipi_dsi_detach(dsi);
369 if (ret < 0)357 if (ret < 0)
370 DRM_DEV_ERROR(&dsi->dev, "Failed to detach from DSI host: %d\n",358 dev_err(&dsi->dev, "Failed to detach from DSI host: %d\n", ret);
371 ret);
372 359
373 drm_panel_remove(&ctx->panel);360 drm_panel_remove(&ctx->panel);
374 361
drivers/gpu/drm/panfrost/panfrost_devfreq.c+116−59
@@ -1,20 +1,29 @@
1// SPDX-License-Identifier: GPL-2.01// SPDX-License-Identifier: GPL-2.0
2/* Copyright 2019 Collabora ltd. */2/* Copyright 2019 Collabora ltd. */
3
4#include <linux/clk.h>
3#include <linux/devfreq.h>5#include <linux/devfreq.h>
4#include <linux/devfreq_cooling.h>6#include <linux/devfreq_cooling.h>
5#include <linux/platform_device.h>7#include <linux/platform_device.h>
6#include <linux/pm_opp.h>8#include <linux/pm_opp.h>
7#include <linux/clk.h>
8#include <linux/regulator/consumer.h>
9 9
10#include "panfrost_device.h"10#include "panfrost_device.h"
11#include "panfrost_devfreq.h"11#include "panfrost_devfreq.h"
12#include "panfrost_features.h"
13#include "panfrost_issues.h"
14#include "panfrost_gpu.h"
15#include "panfrost_regs.h"
16 12
17static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev);13static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq)
14{
15 ktime_t now, last;
16
17 now = ktime_get();
18 last = pfdevfreq->time_last_update;
19
20 if (pfdevfreq->busy_count > 0)
21 pfdevfreq->busy_time += ktime_sub(now, last);
22 else
23 pfdevfreq->idle_time += ktime_sub(now, last);
24
25 pfdevfreq->time_last_update = now;
26}
18 27
19static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,28static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
20 u32 flags)29 u32 flags)
@@ -34,30 +43,37 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq, · 13 unmodified lines
34 return 0;43 return 0;
35}44}
36 45
37static void panfrost_devfreq_reset(struct panfrost_device *pfdev)46static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq)
38{47{
39 pfdev->devfreq.busy_time = 0;48 pfdevfreq->busy_time = 0;
40 pfdev->devfreq.idle_time = 0;49 pfdevfreq->idle_time = 0;
41 pfdev->devfreq.time_last_update = ktime_get();50 pfdevfreq->time_last_update = ktime_get();
42}51}
43 52
44static int panfrost_devfreq_get_dev_status(struct device *dev,53static int panfrost_devfreq_get_dev_status(struct device *dev,
45 struct devfreq_dev_status *status)54 struct devfreq_dev_status *status)
46{55{
47 struct panfrost_device *pfdev = dev_get_drvdata(dev);56 struct panfrost_device *pfdev = dev_get_drvdata(dev);
48 57 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
49 panfrost_devfreq_update_utilization(pfdev);58 unsigned long irqflags;
50 59
51 status->current_frequency = clk_get_rate(pfdev->clock);60 status->current_frequency = clk_get_rate(pfdev->clock);
52 status->total_time = ktime_to_ns(ktime_add(pfdev->devfreq.busy_time,
53 pfdev->devfreq.idle_time));
54 61
55 status->busy_time = ktime_to_ns(pfdev->devfreq.busy_time);62 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
63
64 panfrost_devfreq_update_utilization(pfdevfreq);
65
66 status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
67 pfdevfreq->idle_time));
68
69 status->busy_time = ktime_to_ns(pfdevfreq->busy_time);
70
71 panfrost_devfreq_reset(pfdevfreq);
56 72
57 panfrost_devfreq_reset(pfdev);73 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
58 74
59 dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", status->busy_time,75 dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
60 status->total_time,76 status->busy_time, status->total_time,
61 status->busy_time / (status->total_time / 100),77 status->busy_time / (status->total_time / 100),
62 status->current_frequency / 1000 / 1000);78 status->current_frequency / 1000 / 1000);
63 79
@@ -77,21 +93,43 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) · 13 unmodified lines
77 unsigned long cur_freq;93 unsigned long cur_freq;
78 struct device *dev = &pfdev->pdev->dev;94 struct device *dev = &pfdev->pdev->dev;
79 struct devfreq *devfreq;95 struct devfreq *devfreq;
96 struct opp_table *opp_table;
80 struct thermal_cooling_device *cooling;97 struct thermal_cooling_device *cooling;
98 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
99
100 opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
101 pfdev->comp->num_supplies);
102 if (IS_ERR(opp_table)) {
103 ret = PTR_ERR(opp_table);
104 /* Continue if the optional regulator is missing */
105 if (ret != -ENODEV) {
106 DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
107 goto err_fini;
108 }
109 } else {
110 pfdevfreq->regulators_opp_table = opp_table;
111 }
81 112
82 ret = dev_pm_opp_of_add_table(dev);113 ret = dev_pm_opp_of_add_table(dev);
83 if (ret == -ENODEV) /* Optional, continue without devfreq */114 if (ret) {
84 return 0;115 /* Optional, continue without devfreq */
85 else if (ret)116 if (ret == -ENODEV)
86 return ret;117 ret = 0;
118 goto err_fini;
119 }
120 pfdevfreq->opp_of_table_added = true;
121
122 spin_lock_init(&pfdevfreq->lock);
87 123
88 panfrost_devfreq_reset(pfdev);124 panfrost_devfreq_reset(pfdevfreq);
89 125
90 cur_freq = clk_get_rate(pfdev->clock);126 cur_freq = clk_get_rate(pfdev->clock);
91 127
92 opp = devfreq_recommended_opp(dev, &cur_freq, 0);128 opp = devfreq_recommended_opp(dev, &cur_freq, 0);
93 if (IS_ERR(opp))129 if (IS_ERR(opp)) {
94 return PTR_ERR(opp);130 ret = PTR_ERR(opp);
131 goto err_fini;
132 }
95 133
96 panfrost_devfreq_profile.initial_freq = cur_freq;134 panfrost_devfreq_profile.initial_freq = cur_freq;
97 dev_pm_opp_put(opp);135 dev_pm_opp_put(opp);
@@ -100,75 +138,94 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev) · 2 unmodified lines
100 DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);138 DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
101 if (IS_ERR(devfreq)) {139 if (IS_ERR(devfreq)) {
102 DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");140 DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
103 dev_pm_opp_of_remove_table(dev);141 ret = PTR_ERR(devfreq);
104 return PTR_ERR(devfreq);142 goto err_fini;
105 }143 }
106 pfdev->devfreq.devfreq = devfreq;144 pfdevfreq->devfreq = devfreq;
107 145
108 cooling = of_devfreq_cooling_register(dev->of_node, devfreq);146 cooling = of_devfreq_cooling_register(dev->of_node, devfreq);
109 if (IS_ERR(cooling))147 if (IS_ERR(cooling))
110 DRM_DEV_INFO(dev, "Failed to register cooling device\n");148 DRM_DEV_INFO(dev, "Failed to register cooling device\n");
111 else149 else
112 pfdev->devfreq.cooling = cooling;150 pfdevfreq->cooling = cooling;
113 151
114 return 0;152 return 0;
153
154err_fini:
155 panfrost_devfreq_fini(pfdev);
156 return ret;
115}157}
116 158
117void panfrost_devfreq_fini(struct panfrost_device *pfdev)159void panfrost_devfreq_fini(struct panfrost_device *pfdev)
118{160{
119 if (pfdev->devfreq.cooling)161 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
120 devfreq_cooling_unregister(pfdev->devfreq.cooling);162
121 dev_pm_opp_of_remove_table(&pfdev->pdev->dev);163 if (pfdevfreq->cooling) {
164 devfreq_cooling_unregister(pfdevfreq->cooling);
165 pfdevfreq->cooling = NULL;
166 }
167
168 if (pfdevfreq->opp_of_table_added) {
169 dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
170 pfdevfreq->opp_of_table_added = false;
171 }
172
173 if (pfdevfreq->regulators_opp_table) {
174 dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table);
175 pfdevfreq->regulators_opp_table = NULL;
176 }
122}177}
123 178
124void panfrost_devfreq_resume(struct panfrost_device *pfdev)179void panfrost_devfreq_resume(struct panfrost_device *pfdev)
125{180{
126 if (!pfdev->devfreq.devfreq)181 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
182
183 if (!pfdevfreq->devfreq)
127 return;184 return;
128 185
129 panfrost_devfreq_reset(pfdev);186 panfrost_devfreq_reset(pfdevfreq);
130 187
131 devfreq_resume_device(pfdev->devfreq.devfreq);188 devfreq_resume_device(pfdevfreq->devfreq);
132}189}
133 190
134void panfrost_devfreq_suspend(struct panfrost_device *pfdev)191void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
135{192{
136 if (!pfdev->devfreq.devfreq)193 struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
194
195 if (!pfdevfreq->devfreq)
137 return;196 return;
138 197
139 devfreq_suspend_device(pfdev->devfreq.devfreq);198 devfreq_suspend_device(pfdevfreq->devfreq);
140}199}
141 200
142static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev)201void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq)
143{202{
144 ktime_t now;203 unsigned long irqflags;
145 ktime_t last;
146 204
147 if (!pfdev->devfreq.devfreq)205 if (!pfdevfreq->devfreq)
148 return;206 return;
149 207
150 now = ktime_get();208 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
151 last = pfdev->devfreq.time_last_update;
152 209
153 if (atomic_read(&pfdev->devfreq.busy_count) > 0)210 panfrost_devfreq_update_utilization(pfdevfreq);
154 pfdev->devfreq.busy_time += ktime_sub(now, last);
155 else
156 pfdev->devfreq.idle_time += ktime_sub(now, last);
157 211
158 pfdev->devfreq.time_last_update = now;212 pfdevfreq->busy_count++;
159}
160 213
161void panfrost_devfreq_record_busy(struct panfrost_device *pfdev)214 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
162{
163 panfrost_devfreq_update_utilization(pfdev);
164 atomic_inc(&pfdev->devfreq.busy_count);
165}215}
166 216
167void panfrost_devfreq_record_idle(struct panfrost_device *pfdev)217void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
168{218{
169 int count;219 unsigned long irqflags;
220
221 if (!pfdevfreq->devfreq)
222 return;
223
224 spin_lock_irqsave(&pfdevfreq->lock, irqflags);
225
226 panfrost_devfreq_update_utilization(pfdevfreq);
227
228 WARN_ON(--pfdevfreq->busy_count < 0);
170 229
171 panfrost_devfreq_update_utilization(pfdev);230 spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
172 count = atomic_dec_if_positive(&pfdev->devfreq.busy_count);
173 WARN_ON(count < 0);
174}231}
drivers/gpu/drm/panfrost/panfrost_devfreq.h+28−2
@@ -4,13 +4,39 @@ · 3 unmodified lines
4#ifndef __PANFROST_DEVFREQ_H__4#ifndef __PANFROST_DEVFREQ_H__
5#define __PANFROST_DEVFREQ_H__5#define __PANFROST_DEVFREQ_H__
6 6
7#include <linux/spinlock.h>
8#include <linux/ktime.h>
9
10struct devfreq;
11struct opp_table;
12struct thermal_cooling_device;
13
14struct panfrost_device;
15
16struct panfrost_devfreq {
17 struct devfreq *devfreq;
18 struct opp_table *regulators_opp_table;
19 struct thermal_cooling_device *cooling;
20 bool opp_of_table_added;
21
22 ktime_t busy_time;
23 ktime_t idle_time;
24 ktime_t time_last_update;
25 int busy_count;
26 /*
27 * Protect busy_time, idle_time, time_last_update and busy_count
28 * because these can be updated concurrently between multiple jobs.
29 */
30 spinlock_t lock;
31};
32
7int panfrost_devfreq_init(struct panfrost_device *pfdev);33int panfrost_devfreq_init(struct panfrost_device *pfdev);
8void panfrost_devfreq_fini(struct panfrost_device *pfdev);34void panfrost_devfreq_fini(struct panfrost_device *pfdev);
9 35
10void panfrost_devfreq_resume(struct panfrost_device *pfdev);36void panfrost_devfreq_resume(struct panfrost_device *pfdev);
11void panfrost_devfreq_suspend(struct panfrost_device *pfdev);37void panfrost_devfreq_suspend(struct panfrost_device *pfdev);
12 38
13void panfrost_devfreq_record_busy(struct panfrost_device *pfdev);39void panfrost_devfreq_record_busy(struct panfrost_devfreq *devfreq);
14void panfrost_devfreq_record_idle(struct panfrost_device *pfdev);40void panfrost_devfreq_record_idle(struct panfrost_devfreq *devfreq);
15 41
16#endif /* __PANFROST_DEVFREQ_H__ */42#endif /* __PANFROST_DEVFREQ_H__ */
drivers/gpu/drm/panfrost/panfrost_device.c+39−22
@@ -90,9 +90,11 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev) · 89 unmodified lines
90{90{
91 int ret, i;91 int ret, i;
92 92
93 if (WARN(pfdev->comp->num_supplies > ARRAY_SIZE(pfdev->regulators),93 pfdev->regulators = devm_kcalloc(pfdev->dev, pfdev->comp->num_supplies,
94 "Too many supplies in compatible structure.\n"))94 sizeof(*pfdev->regulators),
95 return -EINVAL;95 GFP_KERNEL);
96 if (!pfdev->regulators)
97 return -ENOMEM;
96 98
97 for (i = 0; i < pfdev->comp->num_supplies; i++)99 for (i = 0; i < pfdev->comp->num_supplies; i++)
98 pfdev->regulators[i].supply = pfdev->comp->supply_names[i];100 pfdev->regulators[i].supply = pfdev->comp->supply_names[i];
@@ -119,8 +121,10 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev) · 20 unmodified lines
119 121
120static void panfrost_regulator_fini(struct panfrost_device *pfdev)122static void panfrost_regulator_fini(struct panfrost_device *pfdev)
121{123{
122 regulator_bulk_disable(pfdev->comp->num_supplies,124 if (!pfdev->regulators)
123 pfdev->regulators);125 return;
126
127 regulator_bulk_disable(pfdev->comp->num_supplies, pfdev->regulators);
124}128}
125 129
126static void panfrost_pm_domain_fini(struct panfrost_device *pfdev)130static void panfrost_pm_domain_fini(struct panfrost_device *pfdev)
@@ -214,58 +218,70 @@ int panfrost_device_init(struct panfrost_device *pfdev) · 87 unmodified lines
214 return err;218 return err;
215 }219 }
216 220
217 err = panfrost_regulator_init(pfdev);221 err = panfrost_devfreq_init(pfdev);
218 if (err)222 if (err) {
219 goto err_out0;223 if (err != -EPROBE_DEFER)
224 dev_err(pfdev->dev, "devfreq init failed %d\n", err);
225 goto out_clk;
226 }
227
228 /* OPP will handle regulators */
229 if (!pfdev->pfdevfreq.opp_of_table_added) {
230 err = panfrost_regulator_init(pfdev);
231 if (err)
232 goto out_devfreq;
233 }
220 234
221 err = panfrost_reset_init(pfdev);235 err = panfrost_reset_init(pfdev);
222 if (err) {236 if (err) {
223 dev_err(pfdev->dev, "reset init failed %d\n", err);237 dev_err(pfdev->dev, "reset init failed %d\n", err);
224 goto err_out1;238 goto out_regulator;
225 }239 }
226 240
227 err = panfrost_pm_domain_init(pfdev);241 err = panfrost_pm_domain_init(pfdev);
228 if (err)242 if (err)
229 goto err_out2;243 goto out_reset;
230 244
231 res = platform_get_resource(pfdev->pdev, IORESOURCE_MEM, 0);245 res = platform_get_resource(pfdev->pdev, IORESOURCE_MEM, 0);
232 pfdev->iomem = devm_ioremap_resource(pfdev->dev, res);246 pfdev->iomem = devm_ioremap_resource(pfdev->dev, res);
233 if (IS_ERR(pfdev->iomem)) {247 if (IS_ERR(pfdev->iomem)) {
234 dev_err(pfdev->dev, "failed to ioremap iomem\n");248 dev_err(pfdev->dev, "failed to ioremap iomem\n");
235 err = PTR_ERR(pfdev->iomem);249 err = PTR_ERR(pfdev->iomem);
236 goto err_out3;250 goto out_pm_domain;
237 }251 }
238 252
239 err = panfrost_gpu_init(pfdev);253 err = panfrost_gpu_init(pfdev);
240 if (err)254 if (err)
241 goto err_out3;255 goto out_pm_domain;
242 256
243 err = panfrost_mmu_init(pfdev);257 err = panfrost_mmu_init(pfdev);
244 if (err)258 if (err)
245 goto err_out4;259 goto out_gpu;
246 260
247 err = panfrost_job_init(pfdev);261 err = panfrost_job_init(pfdev);
248 if (err)262 if (err)
249 goto err_out5;263 goto out_mmu;
250 264
251 err = panfrost_perfcnt_init(pfdev);265 err = panfrost_perfcnt_init(pfdev);
252 if (err)266 if (err)
253 goto err_out6;267 goto out_job;
254 268
255 return 0;269 return 0;
256err_out6:270out_job:
257 panfrost_job_fini(pfdev);271 panfrost_job_fini(pfdev);
258err_out5:272out_mmu:
259 panfrost_mmu_fini(pfdev);273 panfrost_mmu_fini(pfdev);
260err_out4:274out_gpu:
261 panfrost_gpu_fini(pfdev);275 panfrost_gpu_fini(pfdev);
262err_out3:276out_pm_domain:
263 panfrost_pm_domain_fini(pfdev);277 panfrost_pm_domain_fini(pfdev);
264err_out2:278out_reset:
265 panfrost_reset_fini(pfdev);279 panfrost_reset_fini(pfdev);
266err_out1:280out_regulator:
267 panfrost_regulator_fini(pfdev);281 panfrost_regulator_fini(pfdev);
268err_out0:282out_devfreq:
283 panfrost_devfreq_fini(pfdev);
284out_clk:
269 panfrost_clk_fini(pfdev);285 panfrost_clk_fini(pfdev);
270 return err;286 return err;
271}287}
@@ -278,6 +294,7 @@ void panfrost_device_fini(struct panfrost_device *pfdev) · 6 unmodified lines
278 panfrost_gpu_fini(pfdev);294 panfrost_gpu_fini(pfdev);
279 panfrost_pm_domain_fini(pfdev);295 panfrost_pm_domain_fini(pfdev);
280 panfrost_reset_fini(pfdev);296 panfrost_reset_fini(pfdev);
297 panfrost_devfreq_fini(pfdev);
281 panfrost_regulator_fini(pfdev);298 panfrost_regulator_fini(pfdev);
282 panfrost_clk_fini(pfdev);299 panfrost_clk_fini(pfdev);
283}300}
drivers/gpu/drm/panfrost/panfrost_device.h+4−10
@@ -13,6 +13,8 @@ · 12 unmodified lines
13#include <drm/drm_mm.h>13#include <drm/drm_mm.h>
14#include <drm/gpu_scheduler.h>14#include <drm/gpu_scheduler.h>
15 15
16#include "panfrost_devfreq.h"
17
16struct panfrost_device;18struct panfrost_device;
17struct panfrost_mmu;19struct panfrost_mmu;
18struct panfrost_job_slot;20struct panfrost_job_slot;
@@ -20,7 +22,6 @@ struct panfrost_job; · 1 unmodified line
20struct panfrost_perfcnt;22struct panfrost_perfcnt;
21 23
22#define NUM_JOB_SLOTS 324#define NUM_JOB_SLOTS 3
23#define MAX_REGULATORS 2
24#define MAX_PM_DOMAINS 325#define MAX_PM_DOMAINS 3
25 26
26struct panfrost_features {27struct panfrost_features {
@@ -79,7 +80,7 @@ struct panfrost_device { · 52 unmodified lines
79 void __iomem *iomem;80 void __iomem *iomem;
80 struct clk *clock;81 struct clk *clock;
81 struct clk *bus_clock;82 struct clk *bus_clock;
82 struct regulator_bulk_data regulators[MAX_REGULATORS];83 struct regulator_bulk_data *regulators;
83 struct reset_control *rstc;84 struct reset_control *rstc;
84 /* pm_domains for devices with more than one. */85 /* pm_domains for devices with more than one. */
85 struct device *pm_domain_devs[MAX_PM_DOMAINS];86 struct device *pm_domain_devs[MAX_PM_DOMAINS];
@@ -107,14 +108,7 @@ struct panfrost_device { · 21 unmodified lines
107 struct list_head shrinker_list;108 struct list_head shrinker_list;
108 struct shrinker shrinker;109 struct shrinker shrinker;
109 110
110 struct {111 struct panfrost_devfreq pfdevfreq;
111 struct devfreq *devfreq;
112 struct thermal_cooling_device *cooling;
113 ktime_t busy_time;
114 ktime_t idle_time;
115 ktime_t time_last_update;
116 atomic_t busy_count;
117 } devfreq;
118};112};
119 113
120struct panfrost_mmu {114struct panfrost_mmu {
drivers/gpu/drm/panfrost/panfrost_drv.c+3−13
@@ -14,7 +14,6 @@ · 13 unmodified lines
14#include <drm/drm_utils.h>14#include <drm/drm_utils.h>
15 15
16#include "panfrost_device.h"16#include "panfrost_device.h"
17#include "panfrost_devfreq.h"
18#include "panfrost_gem.h"17#include "panfrost_gem.h"
19#include "panfrost_mmu.h"18#include "panfrost_mmu.h"
20#include "panfrost_job.h"19#include "panfrost_job.h"
@@ -606,13 +605,6 @@ static int panfrost_probe(struct platform_device *pdev) · 585 unmodified lines
606 goto err_out0;605 goto err_out0;
607 }606 }
608 607
609 err = panfrost_devfreq_init(pfdev);
610 if (err) {
611 if (err != -EPROBE_DEFER)
612 dev_err(&pdev->dev, "Fatal error during devfreq init\n");
613 goto err_out1;
614 }
615
616 pm_runtime_set_active(pfdev->dev);608 pm_runtime_set_active(pfdev->dev);
617 pm_runtime_mark_last_busy(pfdev->dev);609 pm_runtime_mark_last_busy(pfdev->dev);
618 pm_runtime_enable(pfdev->dev);610 pm_runtime_enable(pfdev->dev);
@@ -625,16 +617,14 @@ static int panfrost_probe(struct platform_device *pdev) · 6 unmodified lines
625 */617 */
626 err = drm_dev_register(ddev, 0);618 err = drm_dev_register(ddev, 0);
627 if (err < 0)619 if (err < 0)
628 goto err_out2;620 goto err_out1;
629 621
630 panfrost_gem_shrinker_init(ddev);622 panfrost_gem_shrinker_init(ddev);
631 623
632 return 0;624 return 0;
633 625
634err_out2:
635 pm_runtime_disable(pfdev->dev);
636 panfrost_devfreq_fini(pfdev);
637err_out1:626err_out1:
627 pm_runtime_disable(pfdev->dev);
638 panfrost_device_fini(pfdev);628 panfrost_device_fini(pfdev);
639err_out0:629err_out0:
640 drm_dev_put(ddev);630 drm_dev_put(ddev);
@@ -650,7 +640,6 @@ static int panfrost_remove(struct platform_device *pdev) · 9 unmodified lines
650 panfrost_gem_shrinker_cleanup(ddev);640 panfrost_gem_shrinker_cleanup(ddev);
651 641
652 pm_runtime_get_sync(pfdev->dev);642 pm_runtime_get_sync(pfdev->dev);
653 panfrost_devfreq_fini(pfdev);
654 panfrost_device_fini(pfdev);643 panfrost_device_fini(pfdev);
655 pm_runtime_put_sync_suspend(pfdev->dev);644 pm_runtime_put_sync_suspend(pfdev->dev);
656 pm_runtime_disable(pfdev->dev);645 pm_runtime_disable(pfdev->dev);
@@ -677,6 +666,7 @@ static const struct of_device_id dt_match[] = { · 20 unmodified lines
677 { .compatible = "arm,mali-t830", .data = &default_data, },666 { .compatible = "arm,mali-t830", .data = &default_data, },
678 { .compatible = "arm,mali-t860", .data = &default_data, },667 { .compatible = "arm,mali-t860", .data = &default_data, },
679 { .compatible = "arm,mali-t880", .data = &default_data, },668 { .compatible = "arm,mali-t880", .data = &default_data, },
669 { .compatible = "arm,mali-bifrost", .data = &default_data, },
680 {}670 {}
681};671};
682MODULE_DEVICE_TABLE(of, dt_match);672MODULE_DEVICE_TABLE(of, dt_match);
drivers/gpu/drm/panfrost/panfrost_gpu.c+12−2
@@ -10,6 +10,7 @@ · 9 unmodified lines
10#include <linux/io.h>10#include <linux/io.h>
11#include <linux/iopoll.h>11#include <linux/iopoll.h>
12#include <linux/platform_device.h>12#include <linux/platform_device.h>
13#include <linux/pm_runtime.h>
13 14
14#include "panfrost_device.h"15#include "panfrost_device.h"
15#include "panfrost_features.h"16#include "panfrost_features.h"
@@ -368,7 +369,16 @@ void panfrost_gpu_fini(struct panfrost_device *pfdev) · 352 unmodified lines
368 369
369u32 panfrost_gpu_get_latest_flush_id(struct panfrost_device *pfdev)370u32 panfrost_gpu_get_latest_flush_id(struct panfrost_device *pfdev)
370{371{
371 if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))372 u32 flush_id;
372 return gpu_read(pfdev, GPU_LATEST_FLUSH_ID);373
374 if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION)) {
375 /* Flush reduction only makes sense when the GPU is kept powered on between jobs */
376 if (pm_runtime_get_if_in_use(pfdev->dev)) {
377 flush_id = gpu_read(pfdev, GPU_LATEST_FLUSH_ID);
378 pm_runtime_put(pfdev->dev);
379 return flush_id;
380 }
381 }
382
373 return 0;383 return 0;
374}384}
drivers/gpu/drm/panfrost/panfrost_job.c+3−7
@@ -145,7 +145,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js) · 144 unmodified lines
145 u64 jc_head = job->jc;145 u64 jc_head = job->jc;
146 int ret;146 int ret;
147 147
148 panfrost_devfreq_record_busy(pfdev);148 panfrost_devfreq_record_busy(&pfdev->pfdevfreq);
149 149
150 ret = pm_runtime_get_sync(pfdev->dev);150 ret = pm_runtime_get_sync(pfdev->dev);
151 if (ret < 0)151 if (ret < 0)
@@ -410,7 +410,7 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) · 258 unmodified lines
410 for (i = 0; i < NUM_JOB_SLOTS; i++) {410 for (i = 0; i < NUM_JOB_SLOTS; i++) {
411 if (pfdev->jobs[i]) {411 if (pfdev->jobs[i]) {
412 pm_runtime_put_noidle(pfdev->dev);412 pm_runtime_put_noidle(pfdev->dev);
413 panfrost_devfreq_record_idle(pfdev);413 panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
414 pfdev->jobs[i] = NULL;414 pfdev->jobs[i] = NULL;
415 }415 }
416 }416 }
@@ -478,7 +478,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data) · 61 unmodified lines
478 pfdev->jobs[j] = NULL;478 pfdev->jobs[j] = NULL;
479 479
480 panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);480 panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);
481 panfrost_devfreq_record_idle(pfdev);481 panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
482 482
483 dma_fence_signal_locked(job->done_fence);483 dma_fence_signal_locked(job->done_fence);
484 pm_runtime_put_autosuspend(pfdev->dev);484 pm_runtime_put_autosuspend(pfdev->dev);
@@ -581,10 +581,6 @@ int panfrost_job_is_idle(struct panfrost_device *pfdev) · 96 unmodified lines
581 struct panfrost_job_slot *js = pfdev->js;581 struct panfrost_job_slot *js = pfdev->js;
582 int i;582 int i;
583 583
584 /* Check whether the hardware is idle */
585 if (atomic_read(&pfdev->devfreq.busy_count))
586 return false;
587
588 for (i = 0; i < NUM_JOB_SLOTS; i++) {584 for (i = 0; i < NUM_JOB_SLOTS; i++) {
589 /* If there are any jobs in the HW queue, we're not idle */585 /* If there are any jobs in the HW queue, we're not idle */
590 if (atomic_read(&js->queue[i].sched.hw_rq_count))586 if (atomic_read(&js->queue[i].sched.hw_rq_count))
drivers/gpu/drm/panfrost/panfrost_perfcnt.c+7−3
@@ -83,11 +83,13 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev, · 82 unmodified lines
83 83
84 ret = pm_runtime_get_sync(pfdev->dev);84 ret = pm_runtime_get_sync(pfdev->dev);
85 if (ret < 0)85 if (ret < 0)
86 return ret;86 goto err_put_pm;
87 87
88 bo = drm_gem_shmem_create(pfdev->ddev, perfcnt->bosize);88 bo = drm_gem_shmem_create(pfdev->ddev, perfcnt->bosize);
89 if (IS_ERR(bo))89 if (IS_ERR(bo)) {
90 return PTR_ERR(bo);90 ret = PTR_ERR(bo);
91 goto err_put_pm;
92 }
91 93
92 /* Map the perfcnt buf in the address space attached to file_priv. */94 /* Map the perfcnt buf in the address space attached to file_priv. */
93 ret = panfrost_gem_open(&bo->base, file_priv);95 ret = panfrost_gem_open(&bo->base, file_priv);
@@ -168,6 +170,8 @@ err_close_bo: · 74 unmodified lines
168 panfrost_gem_close(&bo->base, file_priv);170 panfrost_gem_close(&bo->base, file_priv);
169err_put_bo:171err_put_bo:
170 drm_gem_object_put(&bo->base);172 drm_gem_object_put(&bo->base);
173err_put_pm:
174 pm_runtime_put(pfdev->dev);
171 return ret;175 return ret;
172}176}
173 177
drivers/gpu/drm/pl111/pl111_drv.c+5−15
@@ -10,18 +10,11 @@ · 9 unmodified lines
10 */10 */
11 11
12/**12/**
13 * DOC: ARM PrimeCell PL111 CLCD Driver13 * DOC: ARM PrimeCell PL110 and PL111 CLCD Driver
14 *14 *
15 * The PL111 is a simple LCD controller that can support TFT and STN15 * The PL110/PL111 is a simple LCD controller that can support TFT
16 * displays. This driver exposes a standard KMS interface for them.16 * and STN displays. This driver exposes a standard KMS interface
17 *17 * for them.
18 * This driver uses the same Device Tree binding as the fbdev CLCD
19 * driver. While the fbdev driver supports panels that may be
20 * connected to the CLCD internally to the CLCD driver, in DRM the
21 * panels get split out to drivers/gpu/drm/panels/. This means that,
22 * in converting from using fbdev to using DRM, you also need to write
23 * a panel driver (which may be as simple as an entry in
24 * panel-simple.c).
25 *18 *
26 * The driver currently doesn't expose the cursor. The DRM API for19 * The driver currently doesn't expose the cursor. The DRM API for
27 * cursors requires support for 64x64 ARGB8888 cursor images, while20 * cursors requires support for 64x64 ARGB8888 cursor images, while
@@ -29,16 +22,13 @@ · 1 unmodified line
29 * cursors. While one could imagine trying to hack something together22 * cursors. While one could imagine trying to hack something together
30 * to look at the ARGB8888 and program reasonable in monochrome, we23 * to look at the ARGB8888 and program reasonable in monochrome, we
31 * just don't expose the cursor at all instead, and leave cursor24 * just don't expose the cursor at all instead, and leave cursor
32 * support to the X11 software cursor layer.25 * support to the application software cursor layer.
33 *26 *
34 * TODO:27 * TODO:
35 *28 *
36 * - Fix race between setting plane base address and getting IRQ for29 * - Fix race between setting plane base address and getting IRQ for
37 * vsync firing the pageflip completion.30 * vsync firing the pageflip completion.
38 *31 *
39 * - Use the "max-memory-bandwidth" DT property to filter the
40 * supported formats.
41 *
42 * - Read back hardware state at boot to skip reprogramming the32 * - Read back hardware state at boot to skip reprogramming the
43 * hardware when doing a no-op modeset.33 * hardware when doing a no-op modeset.
44 *34 *
drivers/gpu/drm/qxl/qxl_cmd.c+1−1
@@ -588,7 +588,7 @@ static int qxl_reap_surf(struct qxl_device *qdev, struct qxl_bo *surf, bool stal · 587 unmodified lines
588{588{
589 int ret;589 int ret;
590 590
591 ret = qxl_bo_reserve(surf, false);591 ret = qxl_bo_reserve(surf);
592 if (ret)592 if (ret)
593 return ret;593 return ret;
594 594
drivers/gpu/drm/qxl/qxl_display.c+11−10
@@ -162,7 +162,8 @@ static void qxl_update_offset_props(struct qxl_device *qdev) · 161 unmodified lines
162void qxl_display_read_client_monitors_config(struct qxl_device *qdev)162void qxl_display_read_client_monitors_config(struct qxl_device *qdev)
163{163{
164 struct drm_device *dev = &qdev->ddev;164 struct drm_device *dev = &qdev->ddev;
165 int status, retries;165 struct drm_modeset_acquire_ctx ctx;
166 int status, retries, ret;
166 167
167 for (retries = 0; retries < 10; retries++) {168 for (retries = 0; retries < 10; retries++) {
168 status = qxl_display_copy_rom_client_monitors_config(qdev);169 status = qxl_display_copy_rom_client_monitors_config(qdev);
@@ -183,9 +184,9 @@ void qxl_display_read_client_monitors_config(struct qxl_device *qdev) · 14 unmodified lines
183 return;184 return;
184 }185 }
185 186
186 drm_modeset_lock_all(dev);187 DRM_MODESET_LOCK_ALL_BEGIN(dev, ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
187 qxl_update_offset_props(qdev);188 qxl_update_offset_props(qdev);
188 drm_modeset_unlock_all(dev);189 DRM_MODESET_LOCK_ALL_END(ctx, ret);
189 if (!drm_helper_hpd_irq_event(dev)) {190 if (!drm_helper_hpd_irq_event(dev)) {
190 /* notify that the monitor configuration changed, to191 /* notify that the monitor configuration changed, to
191 adjust at the arbitrary resolution */192 adjust at the arbitrary resolution */
@@ -403,18 +404,17 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, · 211 unmodified lines
403 struct qxl_device *qdev = to_qxl(fb->dev);404 struct qxl_device *qdev = to_qxl(fb->dev);
404 struct drm_clip_rect norect;405 struct drm_clip_rect norect;
405 struct qxl_bo *qobj;406 struct qxl_bo *qobj;
407 struct drm_modeset_acquire_ctx ctx;
406 bool is_primary;408 bool is_primary;
407 int inc = 1;409 int inc = 1, ret;
408 410
409 drm_modeset_lock_all(fb->dev);411 DRM_MODESET_LOCK_ALL_BEGIN(fb->dev, ctx, DRM_MODESET_ACQUIRE_INTERRUPTIBLE, ret);
410 412
411 qobj = gem_to_qxl_bo(fb->obj[0]);413 qobj = gem_to_qxl_bo(fb->obj[0]);
412 /* if we aren't primary surface ignore this */414 /* if we aren't primary surface ignore this */
413 is_primary = qobj->shadow ? qobj->shadow->is_primary : qobj->is_primary;415 is_primary = qobj->shadow ? qobj->shadow->is_primary : qobj->is_primary;
414 if (!is_primary) {416 if (!is_primary)
415 drm_modeset_unlock_all(fb->dev);417 goto out_lock_end;
416 return 0;
417 }
418 418
419 if (!num_clips) {419 if (!num_clips) {
420 num_clips = 1;420 num_clips = 1;
@@ -430,7 +430,8 @@ static int qxl_framebuffer_surface_dirty(struct drm_framebuffer *fb, · 9 unmodified lines
430 qxl_draw_dirty_fb(qdev, fb, qobj, flags, color,430 qxl_draw_dirty_fb(qdev, fb, qobj, flags, color,
431 clips, num_clips, inc, 0);431 clips, num_clips, inc, 0);
432 432
433 drm_modeset_unlock_all(fb->dev);433out_lock_end:
434 DRM_MODESET_LOCK_ALL_END(ctx, ret);
434 435
435 return 0;436 return 0;
436}437}
drivers/gpu/drm/qxl/qxl_drv.c+3−3
@@ -96,7 +96,7 @@ qxl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 95 unmodified lines
96 if (ret)96 if (ret)
97 goto disable_pci;97 goto disable_pci;
98 98
99 if (is_vga(pdev)) {99 if (is_vga(pdev) && pdev->revision < 5) {
100 ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);100 ret = vga_get_interruptible(pdev, VGA_RSRC_LEGACY_IO);
101 if (ret) {101 if (ret) {
102 DRM_ERROR("can't get legacy vga ioports\n");102 DRM_ERROR("can't get legacy vga ioports\n");
@@ -127,7 +127,7 @@ modeset_cleanup: · 24 unmodified lines
127unload:127unload:
128 qxl_device_fini(qdev);128 qxl_device_fini(qdev);
129put_vga:129put_vga:
130 if (is_vga(pdev))130 if (is_vga(pdev) && pdev->revision < 5)
131 vga_put(pdev, VGA_RSRC_LEGACY_IO);131 vga_put(pdev, VGA_RSRC_LEGACY_IO);
132disable_pci:132disable_pci:
133 pci_disable_device(pdev);133 pci_disable_device(pdev);
@@ -155,7 +155,7 @@ qxl_pci_remove(struct pci_dev *pdev) · 21 unmodified lines
155 155
156 drm_dev_unregister(dev);156 drm_dev_unregister(dev);
157 drm_atomic_helper_shutdown(dev);157 drm_atomic_helper_shutdown(dev);
158 if (is_vga(pdev))158 if (is_vga(pdev) && pdev->revision < 5)
159 vga_put(pdev, VGA_RSRC_LEGACY_IO);159 vga_put(pdev, VGA_RSRC_LEGACY_IO);
160}160}
161 161
drivers/gpu/drm/qxl/qxl_drv.h+1−1
@@ -350,7 +350,7 @@ int qxl_mode_dumb_mmap(struct drm_file *filp, · 349 unmodified lines
350int qxl_ttm_init(struct qxl_device *qdev);350int qxl_ttm_init(struct qxl_device *qdev);
351void qxl_ttm_fini(struct qxl_device *qdev);351void qxl_ttm_fini(struct qxl_device *qdev);
352int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,352int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
353 struct ttm_mem_reg *mem);353 struct ttm_resource *mem);
354 354
355/* qxl image */355/* qxl image */
356 356
drivers/gpu/drm/qxl/qxl_ioctl.c+1−1
@@ -322,7 +322,7 @@ static int qxl_update_area_ioctl(struct drm_device *dev, void *data, · 321 unmodified lines
322 322
323 qobj = gem_to_qxl_bo(gobj);323 qobj = gem_to_qxl_bo(gobj);
324 324
325 ret = qxl_bo_reserve(qobj, false);325 ret = qxl_bo_reserve(qobj);
326 if (ret)326 if (ret)
327 goto out;327 goto out;
328 328
drivers/gpu/drm/qxl/qxl_object.c+2−2
@@ -284,7 +284,7 @@ int qxl_bo_pin(struct qxl_bo *bo) · 283 unmodified lines
284{284{
285 int r;285 int r;
286 286
287 r = qxl_bo_reserve(bo, false);287 r = qxl_bo_reserve(bo);
288 if (r)288 if (r)
289 return r;289 return r;
290 290
@@ -302,7 +302,7 @@ int qxl_bo_unpin(struct qxl_bo *bo) · 11 unmodified lines
302{302{
303 int r;303 int r;
304 304
305 r = qxl_bo_reserve(bo, false);305 r = qxl_bo_reserve(bo);
306 if (r)306 if (r)
307 return r;307 return r;
308 308
drivers/gpu/drm/qxl/qxl_object.h+2−2
@@ -27,11 +27,11 @@ · 26 unmodified lines
27 27
28#include "qxl_drv.h"28#include "qxl_drv.h"
29 29
30static inline int qxl_bo_reserve(struct qxl_bo *bo, bool no_wait)30static inline int qxl_bo_reserve(struct qxl_bo *bo)
31{31{
32 int r;32 int r;
33 33
34 r = ttm_bo_reserve(&bo->tbo, true, no_wait, NULL);34 r = ttm_bo_reserve(&bo->tbo, true, false, NULL);
35 if (unlikely(r != 0)) {35 if (unlikely(r != 0)) {
36 if (r != -ERESTARTSYS) {36 if (r != -ERESTARTSYS) {
37 struct drm_device *ddev = bo->tbo.base.dev;37 struct drm_device *ddev = bo->tbo.base.dev;
drivers/gpu/drm/qxl/qxl_ttm.c+24−51
@@ -48,31 +48,6 @@ static struct qxl_device *qxl_get_qdev(struct ttm_bo_device *bdev) · 47 unmodified lines
48 return qdev;48 return qdev;
49}49}
50 50
51static int qxl_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
52 struct ttm_mem_type_manager *man)
53{
54 switch (type) {
55 case TTM_PL_SYSTEM:
56 /* System memory */
57 man->flags = 0;
58 man->available_caching = TTM_PL_MASK_CACHING;
59 man->default_caching = TTM_PL_FLAG_CACHED;
60 break;
61 case TTM_PL_VRAM:
62 case TTM_PL_PRIV:
63 /* "On-card" video ram */
64 man->func = &ttm_bo_manager_func;
65 man->flags = TTM_MEMTYPE_FLAG_FIXED;
66 man->available_caching = TTM_PL_MASK_CACHING;
67 man->default_caching = TTM_PL_FLAG_CACHED;
68 break;
69 default:
70 DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
71 return -EINVAL;
72 }
73 return 0;
74}
75
76static void qxl_evict_flags(struct ttm_buffer_object *bo,51static void qxl_evict_flags(struct ttm_buffer_object *bo,
77 struct ttm_placement *placement)52 struct ttm_placement *placement)
78{53{
@@ -96,16 +71,10 @@ static void qxl_evict_flags(struct ttm_buffer_object *bo, · 17 unmodified lines
96}71}
97 72
98int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,73int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
99 struct ttm_mem_reg *mem)74 struct ttm_resource *mem)
100{75{
101 struct qxl_device *qdev = qxl_get_qdev(bdev);76 struct qxl_device *qdev = qxl_get_qdev(bdev);
102 77
103 mem->bus.addr = NULL;
104 mem->bus.offset = 0;
105 mem->bus.size = mem->num_pages << PAGE_SHIFT;
106 mem->bus.base = 0;
107 mem->bus.is_iomem = false;
108
109 switch (mem->mem_type) {78 switch (mem->mem_type) {
110 case TTM_PL_SYSTEM:79 case TTM_PL_SYSTEM:
111 /* system memory */80 /* system memory */
@@ -136,7 +105,7 @@ struct qxl_ttm_tt { · 24 unmodified lines
136};105};
137 106
138static int qxl_ttm_backend_bind(struct ttm_tt *ttm,107static int qxl_ttm_backend_bind(struct ttm_tt *ttm,
139 struct ttm_mem_reg *bo_mem)108 struct ttm_resource *bo_mem)
140{109{
141 struct qxl_ttm_tt *gtt = (void *)ttm;110 struct qxl_ttm_tt *gtt = (void *)ttm;
142 111
@@ -188,9 +157,9 @@ static struct ttm_tt *qxl_ttm_tt_create(struct ttm_buffer_object *bo, · 45 unmodified lines
188}157}
189 158
190static void qxl_move_null(struct ttm_buffer_object *bo,159static void qxl_move_null(struct ttm_buffer_object *bo,
191 struct ttm_mem_reg *new_mem)160 struct ttm_resource *new_mem)
192{161{
193 struct ttm_mem_reg *old_mem = &bo->mem;162 struct ttm_resource *old_mem = &bo->mem;
194 163
195 BUG_ON(old_mem->mm_node != NULL);164 BUG_ON(old_mem->mm_node != NULL);
196 *old_mem = *new_mem;165 *old_mem = *new_mem;
@@ -199,9 +168,9 @@ static void qxl_move_null(struct ttm_buffer_object *bo, · 2 unmodified lines
199 168
200static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict,169static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict,
201 struct ttm_operation_ctx *ctx,170 struct ttm_operation_ctx *ctx,
202 struct ttm_mem_reg *new_mem)171 struct ttm_resource *new_mem)
203{172{
204 struct ttm_mem_reg *old_mem = &bo->mem;173 struct ttm_resource *old_mem = &bo->mem;
205 int ret;174 int ret;
206 175
207 ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);176 ret = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
@@ -217,7 +186,7 @@ static int qxl_bo_move(struct ttm_buffer_object *bo, bool evict, · 9 unmodified lines
217 186
218static void qxl_bo_move_notify(struct ttm_buffer_object *bo,187static void qxl_bo_move_notify(struct ttm_buffer_object *bo,
219 bool evict,188 bool evict,
220 struct ttm_mem_reg *new_mem)189 struct ttm_resource *new_mem)
221{190{
222 struct qxl_bo *qbo;191 struct qxl_bo *qbo;
223 struct qxl_device *qdev;192 struct qxl_device *qdev;
@@ -233,7 +202,6 @@ static void qxl_bo_move_notify(struct ttm_buffer_object *bo, · 9 unmodified lines
233 202
234static struct ttm_bo_driver qxl_bo_driver = {203static struct ttm_bo_driver qxl_bo_driver = {
235 .ttm_tt_create = &qxl_ttm_tt_create,204 .ttm_tt_create = &qxl_ttm_tt_create,
236 .init_mem_type = &qxl_init_mem_type,
237 .eviction_valuable = ttm_bo_eviction_valuable,205 .eviction_valuable = ttm_bo_eviction_valuable,
238 .evict_flags = &qxl_evict_flags,206 .evict_flags = &qxl_evict_flags,
239 .move = &qxl_bo_move,207 .move = &qxl_bo_move,
@@ -241,6 +209,14 @@ static struct ttm_bo_driver qxl_bo_driver = { · 1 unmodified line
241 .move_notify = &qxl_bo_move_notify,209 .move_notify = &qxl_bo_move_notify,
242};210};
243 211
212static int qxl_ttm_init_mem_type(struct qxl_device *qdev,
213 unsigned int type,
214 uint64_t size)
215{
216 return ttm_range_man_init(&qdev->mman.bdev, type, TTM_PL_MASK_CACHING,
217 TTM_PL_FLAG_CACHED, false, size);
218}
219
244int qxl_ttm_init(struct qxl_device *qdev)220int qxl_ttm_init(struct qxl_device *qdev)
245{221{
246 int r;222 int r;
@@ -258,14 +234,13 @@ int qxl_ttm_init(struct qxl_device *qdev) · 11 unmodified lines
258 }234 }
259 /* NOTE: this includes the framebuffer (aka surface 0) */235 /* NOTE: this includes the framebuffer (aka surface 0) */
260 num_io_pages = qdev->rom->ram_header_offset / PAGE_SIZE;236 num_io_pages = qdev->rom->ram_header_offset / PAGE_SIZE;
261 r = ttm_bo_init_mm(&qdev->mman.bdev, TTM_PL_VRAM,237 r = qxl_ttm_init_mem_type(qdev, TTM_PL_VRAM, num_io_pages);
262 num_io_pages);
263 if (r) {238 if (r) {
264 DRM_ERROR("Failed initializing VRAM heap.\n");239 DRM_ERROR("Failed initializing VRAM heap.\n");
265 return r;240 return r;
266 }241 }
267 r = ttm_bo_init_mm(&qdev->mman.bdev, TTM_PL_PRIV,242 r = qxl_ttm_init_mem_type(qdev, TTM_PL_PRIV,
268 qdev->surfaceram_size / PAGE_SIZE);243 qdev->surfaceram_size / PAGE_SIZE);
269 if (r) {244 if (r) {
270 DRM_ERROR("Failed initializing Surfaces heap.\n");245 DRM_ERROR("Failed initializing Surfaces heap.\n");
271 return r;246 return r;
@@ -281,8 +256,8 @@ int qxl_ttm_init(struct qxl_device *qdev) · 9 unmodified lines
281 256
282void qxl_ttm_fini(struct qxl_device *qdev)257void qxl_ttm_fini(struct qxl_device *qdev)
283{258{
284 ttm_bo_clean_mm(&qdev->mman.bdev, TTM_PL_VRAM);259 ttm_range_man_fini(&qdev->mman.bdev, TTM_PL_VRAM);
285 ttm_bo_clean_mm(&qdev->mman.bdev, TTM_PL_PRIV);260 ttm_range_man_fini(&qdev->mman.bdev, TTM_PL_PRIV);
286 ttm_bo_device_release(&qdev->mman.bdev);261 ttm_bo_device_release(&qdev->mman.bdev);
287 DRM_INFO("qxl: ttm finalized\n");262 DRM_INFO("qxl: ttm finalized\n");
288}263}
@@ -293,12 +268,10 @@ void qxl_ttm_fini(struct qxl_device *qdev) · 4 unmodified lines
293static int qxl_mm_dump_table(struct seq_file *m, void *data)268static int qxl_mm_dump_table(struct seq_file *m, void *data)
294{269{
295 struct drm_info_node *node = (struct drm_info_node *)m->private;270 struct drm_info_node *node = (struct drm_info_node *)m->private;
296 struct drm_mm *mm = (struct drm_mm *)node->info_ent->data;271 struct ttm_resource_manager *man = (struct ttm_resource_manager *)node->info_ent->data;
297 struct drm_printer p = drm_seq_file_printer(m);272 struct drm_printer p = drm_seq_file_printer(m);
298 273
299 spin_lock(&ttm_bo_glob.lru_lock);274 ttm_resource_manager_debug(man, &p);
300 drm_mm_print(mm, &p);
301 spin_unlock(&ttm_bo_glob.lru_lock);
302 return 0;275 return 0;
303}276}
304#endif277#endif
@@ -319,9 +292,9 @@ void qxl_ttm_debugfs_init(struct qxl_device *qdev) · 14 unmodified lines
319 qxl_mem_types_list[i].show = &qxl_mm_dump_table;292 qxl_mem_types_list[i].show = &qxl_mm_dump_table;
320 qxl_mem_types_list[i].driver_features = 0;293 qxl_mem_types_list[i].driver_features = 0;
321 if (i == 0)294 if (i == 0)
322 qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_VRAM].priv;295 qxl_mem_types_list[i].data = ttm_manager_type(&qdev->mman.bdev, TTM_PL_VRAM);
323 else296 else
324 qxl_mem_types_list[i].data = qdev->mman.bdev.man[TTM_PL_PRIV].priv;297 qxl_mem_types_list[i].data = ttm_manager_type(&qdev->mman.bdev, TTM_PL_PRIV);
325 298
326 }299 }
327 qxl_debugfs_add_files(qdev, qxl_mem_types_list, i);300 qxl_debugfs_add_files(qdev, qxl_mem_types_list, i);
drivers/gpu/drm/radeon/radeon.h+1−1
@@ -2857,7 +2857,7 @@ int radeon_vm_clear_invalids(struct radeon_device *rdev, · 2856 unmodified lines
2857 struct radeon_vm *vm);2857 struct radeon_vm *vm);
2858int radeon_vm_bo_update(struct radeon_device *rdev,2858int radeon_vm_bo_update(struct radeon_device *rdev,
2859 struct radeon_bo_va *bo_va,2859 struct radeon_bo_va *bo_va,
2860 struct ttm_mem_reg *mem);2860 struct ttm_resource *mem);
2861void radeon_vm_bo_invalidate(struct radeon_device *rdev,2861void radeon_vm_bo_invalidate(struct radeon_device *rdev,
2862 struct radeon_bo *bo);2862 struct radeon_bo *bo);
2863struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,2863struct radeon_bo_va *radeon_vm_bo_find(struct radeon_vm *vm,
drivers/gpu/drm/radeon/radeon_gem.c+2−2
@@ -224,9 +224,9 @@ int radeon_gem_info_ioctl(struct drm_device *dev, void *data, · 223 unmodified lines
224{224{
225 struct radeon_device *rdev = dev->dev_private;225 struct radeon_device *rdev = dev->dev_private;
226 struct drm_radeon_gem_info *args = data;226 struct drm_radeon_gem_info *args = data;
227 struct ttm_mem_type_manager *man;227 struct ttm_resource_manager *man;
228 228
229 man = &rdev->mman.bdev.man[TTM_PL_VRAM];229 man = ttm_manager_type(&rdev->mman.bdev, TTM_PL_VRAM);
230 230
231 args->vram_size = (u64)man->size << PAGE_SHIFT;231 args->vram_size = (u64)man->size << PAGE_SHIFT;
232 args->vram_visible = rdev->mc.visible_vram_size;232 args->vram_visible = rdev->mc.visible_vram_size;
drivers/gpu/drm/radeon/radeon_object.c+1−1
@@ -775,7 +775,7 @@ int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, · 774 unmodified lines
775 775
776void radeon_bo_move_notify(struct ttm_buffer_object *bo,776void radeon_bo_move_notify(struct ttm_buffer_object *bo,
777 bool evict,777 bool evict,
778 struct ttm_mem_reg *new_mem)778 struct ttm_resource *new_mem)
779{779{
780 struct radeon_bo *rbo;780 struct radeon_bo *rbo;
781 781
drivers/gpu/drm/radeon/radeon_object.h+1−1
@@ -165,7 +165,7 @@ extern int radeon_bo_check_tiling(struct radeon_bo *bo, bool has_moved, · 164 unmodified lines
165 bool force_drop);165 bool force_drop);
166extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,166extern void radeon_bo_move_notify(struct ttm_buffer_object *bo,
167 bool evict,167 bool evict,
168 struct ttm_mem_reg *new_mem);168 struct ttm_resource *new_mem);
169extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);169extern int radeon_bo_fault_reserve_notify(struct ttm_buffer_object *bo);
170extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);170extern int radeon_bo_get_surface_reg(struct radeon_bo *bo);
171extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence,171extern void radeon_bo_fence(struct radeon_bo *bo, struct radeon_fence *fence,
drivers/gpu/drm/radeon/radeon_ttm.c+41−82
@@ -66,53 +66,20 @@ struct radeon_device *radeon_get_rdev(struct ttm_bo_device *bdev) · 65 unmodified lines
66 return rdev;66 return rdev;
67}67}
68 68
69static int radeon_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,69static int radeon_ttm_init_vram(struct radeon_device *rdev)
70 struct ttm_mem_type_manager *man)
71{70{
72 struct radeon_device *rdev;71 return ttm_range_man_init(&rdev->mman.bdev, TTM_PL_VRAM,
73 72 TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC,
74 rdev = radeon_get_rdev(bdev);73 TTM_PL_FLAG_WC, false,
74 rdev->mc.real_vram_size >> PAGE_SHIFT);
75}
75 76
76 switch (type) {77static int radeon_ttm_init_gtt(struct radeon_device *rdev)
77 case TTM_PL_SYSTEM:78{
78 /* System memory */79 return ttm_range_man_init(&rdev->mman.bdev, TTM_PL_TT,
79 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;80 TTM_PL_MASK_CACHING,
80 man->available_caching = TTM_PL_MASK_CACHING;81 TTM_PL_FLAG_CACHED, true,
81 man->default_caching = TTM_PL_FLAG_CACHED;82 rdev->mc.gtt_size >> PAGE_SHIFT);
82 break;
83 case TTM_PL_TT:
84 man->func = &ttm_bo_manager_func;
85 man->available_caching = TTM_PL_MASK_CACHING;
86 man->default_caching = TTM_PL_FLAG_CACHED;
87 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
88#if IS_ENABLED(CONFIG_AGP)
89 if (rdev->flags & RADEON_IS_AGP) {
90 if (!rdev->ddev->agp) {
91 DRM_ERROR("AGP is not enabled for memory type %u\n",
92 (unsigned)type);
93 return -EINVAL;
94 }
95 if (!rdev->ddev->agp->cant_use_aperture)
96 man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
97 man->available_caching = TTM_PL_FLAG_UNCACHED |
98 TTM_PL_FLAG_WC;
99 man->default_caching = TTM_PL_FLAG_WC;
100 }
101#endif
102 break;
103 case TTM_PL_VRAM:
104 /* "On-card" video ram */
105 man->func = &ttm_bo_manager_func;
106 man->flags = TTM_MEMTYPE_FLAG_FIXED |
107 TTM_MEMTYPE_FLAG_MAPPABLE;
108 man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
109 man->default_caching = TTM_PL_FLAG_WC;
110 break;
111 default:
112 DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
113 return -EINVAL;
114 }
115 return 0;
116}83}
117 84
118static void radeon_evict_flags(struct ttm_buffer_object *bo,85static void radeon_evict_flags(struct ttm_buffer_object *bo,
@@ -182,9 +149,9 @@ static int radeon_verify_access(struct ttm_buffer_object *bo, struct file *filp) · 63 unmodified lines
182}149}
183 150
184static void radeon_move_null(struct ttm_buffer_object *bo,151static void radeon_move_null(struct ttm_buffer_object *bo,
185 struct ttm_mem_reg *new_mem)152 struct ttm_resource *new_mem)
186{153{
187 struct ttm_mem_reg *old_mem = &bo->mem;154 struct ttm_resource *old_mem = &bo->mem;
188 155
189 BUG_ON(old_mem->mm_node != NULL);156 BUG_ON(old_mem->mm_node != NULL);
190 *old_mem = *new_mem;157 *old_mem = *new_mem;
@@ -193,8 +160,8 @@ static void radeon_move_null(struct ttm_buffer_object *bo, · 2 unmodified lines
193 160
194static int radeon_move_blit(struct ttm_buffer_object *bo,161static int radeon_move_blit(struct ttm_buffer_object *bo,
195 bool evict, bool no_wait_gpu,162 bool evict, bool no_wait_gpu,
196 struct ttm_mem_reg *new_mem,163 struct ttm_resource *new_mem,
197 struct ttm_mem_reg *old_mem)164 struct ttm_resource *old_mem)
198{165{
199 struct radeon_device *rdev;166 struct radeon_device *rdev;
200 uint64_t old_start, new_start;167 uint64_t old_start, new_start;
@@ -249,11 +216,11 @@ static int radeon_move_blit(struct ttm_buffer_object *bo, · 48 unmodified lines
249static int radeon_move_vram_ram(struct ttm_buffer_object *bo,216static int radeon_move_vram_ram(struct ttm_buffer_object *bo,
250 bool evict, bool interruptible,217 bool evict, bool interruptible,
251 bool no_wait_gpu,218 bool no_wait_gpu,
252 struct ttm_mem_reg *new_mem)219 struct ttm_resource *new_mem)
253{220{
254 struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu };221 struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu };
255 struct ttm_mem_reg *old_mem = &bo->mem;222 struct ttm_resource *old_mem = &bo->mem;
256 struct ttm_mem_reg tmp_mem;223 struct ttm_resource tmp_mem;
257 struct ttm_place placements;224 struct ttm_place placements;
258 struct ttm_placement placement;225 struct ttm_placement placement;
259 int r;226 int r;
@@ -287,18 +254,18 @@ static int radeon_move_vram_ram(struct ttm_buffer_object *bo, · 27 unmodified lines
287 }254 }
288 r = ttm_bo_move_ttm(bo, &ctx, new_mem);255 r = ttm_bo_move_ttm(bo, &ctx, new_mem);
289out_cleanup:256out_cleanup:
290 ttm_bo_mem_put(bo, &tmp_mem);257 ttm_resource_free(bo, &tmp_mem);
291 return r;258 return r;
292}259}
293 260
294static int radeon_move_ram_vram(struct ttm_buffer_object *bo,261static int radeon_move_ram_vram(struct ttm_buffer_object *bo,
295 bool evict, bool interruptible,262 bool evict, bool interruptible,
296 bool no_wait_gpu,263 bool no_wait_gpu,
297 struct ttm_mem_reg *new_mem)264 struct ttm_resource *new_mem)
298{265{
299 struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu };266 struct ttm_operation_ctx ctx = { interruptible, no_wait_gpu };
300 struct ttm_mem_reg *old_mem = &bo->mem;267 struct ttm_resource *old_mem = &bo->mem;
301 struct ttm_mem_reg tmp_mem;268 struct ttm_resource tmp_mem;
302 struct ttm_placement placement;269 struct ttm_placement placement;
303 struct ttm_place placements;270 struct ttm_place placements;
304 int r;271 int r;
@@ -325,17 +292,17 @@ static int radeon_move_ram_vram(struct ttm_buffer_object *bo, · 20 unmodified lines
325 goto out_cleanup;292 goto out_cleanup;
326 }293 }
327out_cleanup:294out_cleanup:
328 ttm_bo_mem_put(bo, &tmp_mem);295 ttm_resource_free(bo, &tmp_mem);
329 return r;296 return r;
330}297}
331 298
332static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,299static int radeon_bo_move(struct ttm_buffer_object *bo, bool evict,
333 struct ttm_operation_ctx *ctx,300 struct ttm_operation_ctx *ctx,
334 struct ttm_mem_reg *new_mem)301 struct ttm_resource *new_mem)
335{302{
336 struct radeon_device *rdev;303 struct radeon_device *rdev;
337 struct radeon_bo *rbo;304 struct radeon_bo *rbo;
338 struct ttm_mem_reg *old_mem = &bo->mem;305 struct ttm_resource *old_mem = &bo->mem;
339 int r;306 int r;
340 307
341 r = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);308 r = ttm_bo_wait(bo, ctx->interruptible, ctx->no_wait_gpu);
@@ -392,18 +359,11 @@ memcpy: · 50 unmodified lines
392 return 0;359 return 0;
393}360}
394 361
395static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)362static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_resource *mem)
396{363{
397 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
398 struct radeon_device *rdev = radeon_get_rdev(bdev);364 struct radeon_device *rdev = radeon_get_rdev(bdev);
365 size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;
399 366
400 mem->bus.addr = NULL;
401 mem->bus.offset = 0;
402 mem->bus.size = mem->num_pages << PAGE_SHIFT;
403 mem->bus.base = 0;
404 mem->bus.is_iomem = false;
405 if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
406 return -EINVAL;
407 switch (mem->mem_type) {367 switch (mem->mem_type) {
408 case TTM_PL_SYSTEM:368 case TTM_PL_SYSTEM:
409 /* system memory */369 /* system memory */
@@ -421,7 +381,7 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_ · 11 unmodified lines
421 case TTM_PL_VRAM:381 case TTM_PL_VRAM:
422 mem->bus.offset = mem->start << PAGE_SHIFT;382 mem->bus.offset = mem->start << PAGE_SHIFT;
423 /* check if it's visible */383 /* check if it's visible */
424 if ((mem->bus.offset + mem->bus.size) > rdev->mc.visible_vram_size)384 if ((mem->bus.offset + bus_size) > rdev->mc.visible_vram_size)
425 return -EINVAL;385 return -EINVAL;
426 mem->bus.base = rdev->mc.aper_base;386 mem->bus.base = rdev->mc.aper_base;
427 mem->bus.is_iomem = true;387 mem->bus.is_iomem = true;
@@ -433,11 +393,11 @@ static int radeon_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_ · 5 unmodified lines
433 if (mem->placement & TTM_PL_FLAG_WC)393 if (mem->placement & TTM_PL_FLAG_WC)
434 mem->bus.addr =394 mem->bus.addr =
435 ioremap_wc(mem->bus.base + mem->bus.offset,395 ioremap_wc(mem->bus.base + mem->bus.offset,
436 mem->bus.size);396 bus_size);
437 else397 else
438 mem->bus.addr =398 mem->bus.addr =
439 ioremap(mem->bus.base + mem->bus.offset,399 ioremap(mem->bus.base + mem->bus.offset,
440 mem->bus.size);400 bus_size);
441 if (!mem->bus.addr)401 if (!mem->bus.addr)
442 return -ENOMEM;402 return -ENOMEM;
443 403
@@ -562,7 +522,7 @@ static void radeon_ttm_tt_unpin_userptr(struct ttm_tt *ttm) · 118 unmodified lines
562}522}
563 523
564static int radeon_ttm_backend_bind(struct ttm_tt *ttm,524static int radeon_ttm_backend_bind(struct ttm_tt *ttm,
565 struct ttm_mem_reg *bo_mem)525 struct ttm_resource *bo_mem)
566{526{
567 struct radeon_ttm_tt *gtt = (void*)ttm;527 struct radeon_ttm_tt *gtt = (void*)ttm;
568 uint32_t flags = RADEON_GART_PAGE_VALID | RADEON_GART_PAGE_READ |528 uint32_t flags = RADEON_GART_PAGE_VALID | RADEON_GART_PAGE_READ |
@@ -760,7 +720,6 @@ static struct ttm_bo_driver radeon_bo_driver = { · 191 unmodified lines
760 .ttm_tt_create = &radeon_ttm_tt_create,720 .ttm_tt_create = &radeon_ttm_tt_create,
761 .ttm_tt_populate = &radeon_ttm_tt_populate,721 .ttm_tt_populate = &radeon_ttm_tt_populate,
762 .ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate,722 .ttm_tt_unpopulate = &radeon_ttm_tt_unpopulate,
763 .init_mem_type = &radeon_init_mem_type,
764 .eviction_valuable = ttm_bo_eviction_valuable,723 .eviction_valuable = ttm_bo_eviction_valuable,
765 .evict_flags = &radeon_evict_flags,724 .evict_flags = &radeon_evict_flags,
766 .move = &radeon_bo_move,725 .move = &radeon_bo_move,
@@ -785,8 +744,8 @@ int radeon_ttm_init(struct radeon_device *rdev) · 18 unmodified lines
785 return r;744 return r;
786 }745 }
787 rdev->mman.initialized = true;746 rdev->mman.initialized = true;
788 r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_VRAM,747
789 rdev->mc.real_vram_size >> PAGE_SHIFT);748 r = radeon_ttm_init_vram(rdev);
790 if (r) {749 if (r) {
791 DRM_ERROR("Failed initializing VRAM heap.\n");750 DRM_ERROR("Failed initializing VRAM heap.\n");
792 return r;751 return r;
@@ -811,8 +770,8 @@ int radeon_ttm_init(struct radeon_device *rdev) · 18 unmodified lines
811 }770 }
812 DRM_INFO("radeon: %uM of VRAM memory ready\n",771 DRM_INFO("radeon: %uM of VRAM memory ready\n",
813 (unsigned) (rdev->mc.real_vram_size / (1024 * 1024)));772 (unsigned) (rdev->mc.real_vram_size / (1024 * 1024)));
814 r = ttm_bo_init_mm(&rdev->mman.bdev, TTM_PL_TT,773
815 rdev->mc.gtt_size >> PAGE_SHIFT);774 r = radeon_ttm_init_gtt(rdev);
816 if (r) {775 if (r) {
817 DRM_ERROR("Failed initializing GTT heap.\n");776 DRM_ERROR("Failed initializing GTT heap.\n");
818 return r;777 return r;
@@ -843,8 +802,8 @@ void radeon_ttm_fini(struct radeon_device *rdev) · 24 unmodified lines
843 }802 }
844 radeon_bo_unref(&rdev->stolen_vga_memory);803 radeon_bo_unref(&rdev->stolen_vga_memory);
845 }804 }
846 ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_VRAM);805 ttm_range_man_fini(&rdev->mman.bdev, TTM_PL_VRAM);
847 ttm_bo_clean_mm(&rdev->mman.bdev, TTM_PL_TT);806 ttm_range_man_fini(&rdev->mman.bdev, TTM_PL_TT);
848 ttm_bo_device_release(&rdev->mman.bdev);807 ttm_bo_device_release(&rdev->mman.bdev);
849 radeon_gart_fini(rdev);808 radeon_gart_fini(rdev);
850 rdev->mman.initialized = false;809 rdev->mman.initialized = false;
@@ -855,12 +814,12 @@ void radeon_ttm_fini(struct radeon_device *rdev) · 4 unmodified lines
855 * isn't running */814 * isn't running */
856void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size)815void radeon_ttm_set_active_vram_size(struct radeon_device *rdev, u64 size)
857{816{
858 struct ttm_mem_type_manager *man;817 struct ttm_resource_manager *man;
859 818
860 if (!rdev->mman.initialized)819 if (!rdev->mman.initialized)
861 return;820 return;
862 821
863 man = &rdev->mman.bdev.man[TTM_PL_VRAM];822 man = ttm_manager_type(&rdev->mman.bdev, TTM_PL_VRAM);
864 /* this just adjusts TTM size idea, which sets lpfn to the correct value */823 /* this just adjusts TTM size idea, which sets lpfn to the correct value */
865 man->size = size >> PAGE_SHIFT;824 man->size = size >> PAGE_SHIFT;
866}825}
@@ -914,7 +873,7 @@ static int radeon_mm_dump_table(struct seq_file *m, void *data) · 47 unmodified lines
914 unsigned ttm_pl = *(int*)node->info_ent->data;873 unsigned ttm_pl = *(int*)node->info_ent->data;
915 struct drm_device *dev = node->minor->dev;874 struct drm_device *dev = node->minor->dev;
916 struct radeon_device *rdev = dev->dev_private;875 struct radeon_device *rdev = dev->dev_private;
917 struct ttm_mem_type_manager *man = &rdev->mman.bdev.man[ttm_pl];876 struct ttm_resource_manager *man = ttm_manager_type(&rdev->mman.bdev, ttm_pl);
918 struct drm_printer p = drm_seq_file_printer(m);877 struct drm_printer p = drm_seq_file_printer(m);
919 878
920 man->func->debug(man, &p);879 man->func->debug(man, &p);
drivers/gpu/drm/radeon/radeon_vm.c+1−1
@@ -911,7 +911,7 @@ static void radeon_vm_fence_pts(struct radeon_vm *vm, · 910 unmodified lines
911 */911 */
912int radeon_vm_bo_update(struct radeon_device *rdev,912int radeon_vm_bo_update(struct radeon_device *rdev,
913 struct radeon_bo_va *bo_va,913 struct radeon_bo_va *bo_va,
914 struct ttm_mem_reg *mem)914 struct ttm_resource *mem)
915{915{
916 struct radeon_vm *vm = bo_va->vm;916 struct radeon_vm *vm = bo_va->vm;
917 struct radeon_ib ib;917 struct radeon_ib ib;
drivers/gpu/drm/rcar-du/rcar_lvds.c+1−5
@@ -677,15 +677,11 @@ static int rcar_lvds_attach(struct drm_bridge *bridge, · 676 unmodified lines
677 if (ret < 0)677 if (ret < 0)
678 return ret;678 return ret;
679 679
680 return drm_panel_attach(lvds->panel, connector);680 return 0;
681}681}
682 682
683static void rcar_lvds_detach(struct drm_bridge *bridge)683static void rcar_lvds_detach(struct drm_bridge *bridge)
684{684{
685 struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge);
686
687 if (lvds->panel)
688 drm_panel_detach(lvds->panel);
689}685}
690 686
691static const struct drm_bridge_funcs rcar_lvds_bridge_ops = {687static const struct drm_bridge_funcs rcar_lvds_bridge_ops = {
drivers/gpu/drm/rockchip/rockchip_lvds.c+0−9
@@ -634,13 +634,6 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master, · 633 unmodified lines
634 "failed to attach encoder: %d\n", ret);634 "failed to attach encoder: %d\n", ret);
635 goto err_free_connector;635 goto err_free_connector;
636 }636 }
637
638 ret = drm_panel_attach(lvds->panel, connector);
639 if (ret < 0) {
640 DRM_DEV_ERROR(drm_dev->dev,
641 "failed to attach panel: %d\n", ret);
642 goto err_free_connector;
643 }
644 } else {637 } else {
645 ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);638 ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
646 if (ret) {639 if (ret) {
@@ -676,8 +669,6 @@ static void rockchip_lvds_unbind(struct device *dev, struct device *master, · 29 unmodified lines
676 669
677 encoder_funcs = lvds->soc_data->helper_funcs;670 encoder_funcs = lvds->soc_data->helper_funcs;
678 encoder_funcs->disable(&lvds->encoder);671 encoder_funcs->disable(&lvds->encoder);
679 if (lvds->panel)
680 drm_panel_detach(lvds->panel);
681 pm_runtime_disable(dev);672 pm_runtime_disable(dev);
682 drm_connector_cleanup(&lvds->connector);673 drm_connector_cleanup(&lvds->connector);
683 drm_encoder_cleanup(&lvds->encoder);674 drm_encoder_cleanup(&lvds->encoder);
drivers/gpu/drm/sti/sti_dvo.c+0−2
@@ -389,8 +389,6 @@ sti_dvo_connector_detect(struct drm_connector *connector, bool force) · 388 unmodified lines
389 dvo->panel = of_drm_find_panel(dvo->panel_node);389 dvo->panel = of_drm_find_panel(dvo->panel_node);
390 if (IS_ERR(dvo->panel))390 if (IS_ERR(dvo->panel))
391 dvo->panel = NULL;391 dvo->panel = NULL;
392 else
393 drm_panel_attach(dvo->panel, connector);
394 }392 }
395 393
396 if (dvo->panel)394 if (dvo->panel)
drivers/gpu/drm/sun4i/sun4i_backend.c+1−1
@@ -769,7 +769,7 @@ static const struct sunxi_engine_ops sun4i_backend_engine_ops = { · 768 unmodified lines
769 .vblank_quirk = sun4i_backend_vblank_quirk,769 .vblank_quirk = sun4i_backend_vblank_quirk,
770};770};
771 771
772static struct regmap_config sun4i_backend_regmap_config = {772static const struct regmap_config sun4i_backend_regmap_config = {
773 .reg_bits = 32,773 .reg_bits = 32,
774 .val_bits = 32,774 .val_bits = 32,
775 .reg_stride = 4,775 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun4i_framebuffer.c+1−1
@@ -35,7 +35,7 @@ static const struct drm_mode_config_funcs sun4i_de_mode_config_funcs = { · 34 unmodified lines
35 .fb_create = drm_gem_fb_create,35 .fb_create = drm_gem_fb_create,
36};36};
37 37
38static struct drm_mode_config_helper_funcs sun4i_de_mode_config_helpers = {38static const struct drm_mode_config_helper_funcs sun4i_de_mode_config_helpers = {
39 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,39 .atomic_commit_tail = drm_atomic_helper_commit_tail_rpm,
40};40};
41 41
drivers/gpu/drm/sun4i/sun4i_frontend.c+1−1
@@ -545,7 +545,7 @@ int sun4i_frontend_enable(struct sun4i_frontend *frontend) · 544 unmodified lines
545}545}
546EXPORT_SYMBOL(sun4i_frontend_enable);546EXPORT_SYMBOL(sun4i_frontend_enable);
547 547
548static struct regmap_config sun4i_frontend_regmap_config = {548static const struct regmap_config sun4i_frontend_regmap_config = {
549 .reg_bits = 32,549 .reg_bits = 32,
550 .val_bits = 32,550 .val_bits = 32,
551 .reg_stride = 4,551 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun4i_lvds.c+1−10
@@ -47,16 +47,13 @@ static int sun4i_lvds_get_modes(struct drm_connector *connector) · 46 unmodified lines
47 return drm_panel_get_modes(lvds->panel, connector);47 return drm_panel_get_modes(lvds->panel, connector);
48}48}
49 49
50static struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = {50static const struct drm_connector_helper_funcs sun4i_lvds_con_helper_funcs = {
51 .get_modes = sun4i_lvds_get_modes,51 .get_modes = sun4i_lvds_get_modes,
52};52};
53 53
54static void54static void
55sun4i_lvds_connector_destroy(struct drm_connector *connector)55sun4i_lvds_connector_destroy(struct drm_connector *connector)
56{56{
57 struct sun4i_lvds *lvds = drm_connector_to_sun4i_lvds(connector);
58
59 drm_panel_detach(lvds->panel);
60 drm_connector_cleanup(connector);57 drm_connector_cleanup(connector);
61}58}
62 59
@@ -141,12 +138,6 @@ int sun4i_lvds_init(struct drm_device *drm, struct sun4i_tcon *tcon) · 78 unmodified lines
141 138
142 drm_connector_attach_encoder(&lvds->connector,139 drm_connector_attach_encoder(&lvds->connector,
143 &lvds->encoder);140 &lvds->encoder);
144
145 ret = drm_panel_attach(lvds->panel, &lvds->connector);
146 if (ret) {
147 dev_err(drm->dev, "Couldn't attach our panel\n");
148 goto err_cleanup_connector;
149 }
150 }141 }
151 142
152 if (bridge) {143 if (bridge) {
drivers/gpu/drm/sun4i/sun4i_rgb.c+2−11
@@ -138,16 +138,13 @@ out: · 137 unmodified lines
138 return MODE_OK;138 return MODE_OK;
139}139}
140 140
141static struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {141static const struct drm_connector_helper_funcs sun4i_rgb_con_helper_funcs = {
142 .get_modes = sun4i_rgb_get_modes,142 .get_modes = sun4i_rgb_get_modes,
143};143};
144 144
145static void145static void
146sun4i_rgb_connector_destroy(struct drm_connector *connector)146sun4i_rgb_connector_destroy(struct drm_connector *connector)
147{147{
148 struct sun4i_rgb *rgb = drm_connector_to_sun4i_rgb(connector);
149
150 drm_panel_detach(rgb->panel);
151 drm_connector_cleanup(connector);148 drm_connector_cleanup(connector);
152}149}
153 150
@@ -183,7 +180,7 @@ static void sun4i_rgb_encoder_disable(struct drm_encoder *encoder) · 29 unmodified lines
183 }180 }
184}181}
185 182
186static struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {183static const struct drm_encoder_helper_funcs sun4i_rgb_enc_helper_funcs = {
187 .disable = sun4i_rgb_encoder_disable,184 .disable = sun4i_rgb_encoder_disable,
188 .enable = sun4i_rgb_encoder_enable,185 .enable = sun4i_rgb_encoder_enable,
189 .mode_valid = sun4i_rgb_mode_valid,186 .mode_valid = sun4i_rgb_mode_valid,
@@ -233,12 +230,6 @@ int sun4i_rgb_init(struct drm_device *drm, struct sun4i_tcon *tcon) · 43 unmodified lines
233 230
234 drm_connector_attach_encoder(&rgb->connector,231 drm_connector_attach_encoder(&rgb->connector,
235 &rgb->encoder);232 &rgb->encoder);
236
237 ret = drm_panel_attach(rgb->panel, &rgb->connector);
238 if (ret) {
239 dev_err(drm->dev, "Couldn't attach our panel\n");
240 goto err_cleanup_connector;
241 }
242 }233 }
243 234
244 if (rgb->bridge) {235 if (rgb->bridge) {
drivers/gpu/drm/sun4i/sun4i_tcon.c+1−1
@@ -825,7 +825,7 @@ static int sun4i_tcon_init_irq(struct device *dev, · 824 unmodified lines
825 return 0;825 return 0;
826}826}
827 827
828static struct regmap_config sun4i_tcon_regmap_config = {828static const struct regmap_config sun4i_tcon_regmap_config = {
829 .reg_bits = 32,829 .reg_bits = 32,
830 .val_bits = 32,830 .val_bits = 32,
831 .reg_stride = 4,831 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun4i_tv.c+3−3
@@ -468,7 +468,7 @@ static void sun4i_tv_mode_set(struct drm_encoder *encoder, · 467 unmodified lines
468 regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);468 regmap_write(tv->regs, SUN4I_TVE_SLAVE_REG, 0);
469}469}
470 470
471static struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {471static const struct drm_encoder_helper_funcs sun4i_tv_helper_funcs = {
472 .disable = sun4i_tv_disable,472 .disable = sun4i_tv_disable,
473 .enable = sun4i_tv_enable,473 .enable = sun4i_tv_enable,
474 .mode_set = sun4i_tv_mode_set,474 .mode_set = sun4i_tv_mode_set,
@@ -504,7 +504,7 @@ static int sun4i_tv_comp_mode_valid(struct drm_connector *connector, · 29 unmodified lines
504 return MODE_OK;504 return MODE_OK;
505}505}
506 506
507static struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = {507static const struct drm_connector_helper_funcs sun4i_tv_comp_connector_helper_funcs = {
508 .get_modes = sun4i_tv_comp_get_modes,508 .get_modes = sun4i_tv_comp_get_modes,
509 .mode_valid = sun4i_tv_comp_mode_valid,509 .mode_valid = sun4i_tv_comp_mode_valid,
510};510};
@@ -523,7 +523,7 @@ static const struct drm_connector_funcs sun4i_tv_comp_connector_funcs = { · 12 unmodified lines
523 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,523 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
524};524};
525 525
526static struct regmap_config sun4i_tv_regmap_config = {526static const struct regmap_config sun4i_tv_regmap_config = {
527 .reg_bits = 32,527 .reg_bits = 32,
528 .val_bits = 32,528 .val_bits = 32,
529 .reg_stride = 4,529 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c+1−4
@@ -820,7 +820,7 @@ static int sun6i_dsi_get_modes(struct drm_connector *connector) · 819 unmodified lines
820 return drm_panel_get_modes(dsi->panel, connector);820 return drm_panel_get_modes(dsi->panel, connector);
821}821}
822 822
823static struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = {823static const struct drm_connector_helper_funcs sun6i_dsi_connector_helper_funcs = {
824 .get_modes = sun6i_dsi_get_modes,824 .get_modes = sun6i_dsi_get_modes,
825};825};
826 826
@@ -973,7 +973,6 @@ static int sun6i_dsi_attach(struct mipi_dsi_host *host, · 146 unmodified lines
973 dsi->panel = panel;973 dsi->panel = panel;
974 dsi->device = device;974 dsi->device = device;
975 975
976 drm_panel_attach(dsi->panel, &dsi->connector);
977 drm_kms_helper_hotplug_event(dsi->drm);976 drm_kms_helper_hotplug_event(dsi->drm);
978 977
979 dev_info(host->dev, "Attached device %s\n", device->name);978 dev_info(host->dev, "Attached device %s\n", device->name);
@@ -985,12 +984,10 @@ static int sun6i_dsi_detach(struct mipi_dsi_host *host, · 5 unmodified lines
985 struct mipi_dsi_device *device)984 struct mipi_dsi_device *device)
986{985{
987 struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);986 struct sun6i_dsi *dsi = host_to_sun6i_dsi(host);
988 struct drm_panel *panel = dsi->panel;
989 987
990 dsi->panel = NULL;988 dsi->panel = NULL;
991 dsi->device = NULL;989 dsi->device = NULL;
992 990
993 drm_panel_detach(panel);
994 drm_kms_helper_hotplug_event(dsi->drm);991 drm_kms_helper_hotplug_event(dsi->drm);
995 992
996 return 0;993 return 0;
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c+1−1
@@ -534,7 +534,7 @@ void sun8i_hdmi_phy_set_ops(struct sun8i_hdmi_phy *phy, · 533 unmodified lines
534 }534 }
535}535}
536 536
537static struct regmap_config sun8i_hdmi_phy_regmap_config = {537static const struct regmap_config sun8i_hdmi_phy_regmap_config = {
538 .reg_bits = 32,538 .reg_bits = 32,
539 .val_bits = 32,539 .val_bits = 32,
540 .reg_stride = 4,540 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun8i_mixer.c+1−1
@@ -303,7 +303,7 @@ static const struct sunxi_engine_ops sun8i_engine_ops = { · 302 unmodified lines
303 .layers_init = sun8i_layers_init,303 .layers_init = sun8i_layers_init,
304};304};
305 305
306static struct regmap_config sun8i_mixer_regmap_config = {306static const struct regmap_config sun8i_mixer_regmap_config = {
307 .reg_bits = 32,307 .reg_bits = 32,
308 .val_bits = 32,308 .val_bits = 32,
309 .reg_stride = 4,309 .reg_stride = 4,
drivers/gpu/drm/sun4i/sun8i_ui_layer.c+1−1
@@ -298,7 +298,7 @@ static void sun8i_ui_layer_atomic_update(struct drm_plane *plane, · 297 unmodified lines
298 true, zpos, old_zpos);298 true, zpos, old_zpos);
299}299}
300 300
301static struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {301static const struct drm_plane_helper_funcs sun8i_ui_layer_helper_funcs = {
302 .prepare_fb = drm_gem_fb_prepare_fb,302 .prepare_fb = drm_gem_fb_prepare_fb,
303 .atomic_check = sun8i_ui_layer_atomic_check,303 .atomic_check = sun8i_ui_layer_atomic_check,
304 .atomic_disable = sun8i_ui_layer_atomic_disable,304 .atomic_disable = sun8i_ui_layer_atomic_disable,
drivers/gpu/drm/sun4i/sun8i_vi_layer.c+1−1
@@ -401,7 +401,7 @@ static void sun8i_vi_layer_atomic_update(struct drm_plane *plane, · 400 unmodified lines
401 true, zpos, old_zpos);401 true, zpos, old_zpos);
402}402}
403 403
404static struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {404static const struct drm_plane_helper_funcs sun8i_vi_layer_helper_funcs = {
405 .prepare_fb = drm_gem_fb_prepare_fb,405 .prepare_fb = drm_gem_fb_prepare_fb,
406 .atomic_check = sun8i_vi_layer_atomic_check,406 .atomic_check = sun8i_vi_layer_atomic_check,
407 .atomic_disable = sun8i_vi_layer_atomic_disable,407 .atomic_disable = sun8i_vi_layer_atomic_disable,
drivers/gpu/drm/tegra/dsi.c+1−3
@@ -1498,10 +1498,8 @@ static int tegra_dsi_host_attach(struct mipi_dsi_host *host, · 1497 unmodified lines
1498 if (IS_ERR(output->panel))1498 if (IS_ERR(output->panel))
1499 output->panel = NULL;1499 output->panel = NULL;
1500 1500
1501 if (output->panel && output->connector.dev) {1501 if (output->panel && output->connector.dev)
1502 drm_panel_attach(output->panel, &output->connector);
1503 drm_helper_hpd_irq_event(output->connector.dev);1502 drm_helper_hpd_irq_event(output->connector.dev);
1504 }
1505 }1503 }
1506 1504
1507 return 0;1505 return 0;
drivers/gpu/drm/tegra/output.c+0−10
@@ -179,13 +179,6 @@ void tegra_output_remove(struct tegra_output *output) · 178 unmodified lines
179int tegra_output_init(struct drm_device *drm, struct tegra_output *output)179int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
180{180{
181 int connector_type;181 int connector_type;
182 int err;
183
184 if (output->panel) {
185 err = drm_panel_attach(output->panel, &output->connector);
186 if (err < 0)
187 return err;
188 }
189 182
190 /*183 /*
191 * The connector is now registered and ready to receive hotplug events184 * The connector is now registered and ready to receive hotplug events
@@ -220,9 +213,6 @@ void tegra_output_exit(struct tegra_output *output) · 28 unmodified lines
220 */213 */
221 if (output->hpd_gpio)214 if (output->hpd_gpio)
222 disable_irq(output->hpd_irq);215 disable_irq(output->hpd_irq);
223
224 if (output->panel)
225 drm_panel_detach(output->panel);
226}216}
227 217
228void tegra_output_find_possible_crtcs(struct tegra_output *output,218void tegra_output_find_possible_crtcs(struct tegra_output *output,
drivers/gpu/drm/tidss/tidss_dispc.c+28−4
@@ -19,6 +19,7 @@ · 18 unmodified lines
19#include <linux/platform_device.h>19#include <linux/platform_device.h>
20#include <linux/pm_runtime.h>20#include <linux/pm_runtime.h>
21#include <linux/regmap.h>21#include <linux/regmap.h>
22#include <linux/sys_soc.h>
22 23
23#include <drm/drm_fourcc.h>24#include <drm/drm_fourcc.h>
24#include <drm/drm_fb_cma_helper.h>25#include <drm/drm_fb_cma_helper.h>
@@ -302,6 +303,8 @@ struct dispc_device { · 277 unmodified lines
302 u32 num_fourccs;303 u32 num_fourccs;
303 304
304 u32 memory_bandwidth_limit;305 u32 memory_bandwidth_limit;
306
307 struct dispc_errata errata;
305};308};
306 309
307static void dispc_write(struct dispc_device *dispc, u16 reg, u32 val)310static void dispc_write(struct dispc_device *dispc, u16 reg, u32 val)
@@ -2641,6 +2644,19 @@ static int dispc_init_am65x_oldi_io_ctrl(struct device *dev, · 2333 unmodified lines
2641 return 0;2644 return 0;
2642}2645}
2643 2646
2647static void dispc_init_errata(struct dispc_device *dispc)
2648{
2649 static const struct soc_device_attribute am65x_sr10_soc_devices[] = {
2650 { .family = "AM65X", .revision = "SR1.0" },
2651 { /* sentinel */ }
2652 };
2653
2654 if (soc_device_match(am65x_sr10_soc_devices)) {
2655 dispc->errata.i2000 = true;
2656 dev_info(dispc->dev, "WA for erratum i2000: YUV formats disabled\n");
2657 }
2658}
2659
2644int dispc_init(struct tidss_device *tidss)2660int dispc_init(struct tidss_device *tidss)
2645{2661{
2646 struct device *dev = tidss->dev;2662 struct device *dev = tidss->dev;
@@ -2664,19 +2680,27 @@ int dispc_init(struct tidss_device *tidss) · 17 unmodified lines
2664 if (!dispc)2680 if (!dispc)
2665 return -ENOMEM;2681 return -ENOMEM;
2666 2682
2683 dispc->tidss = tidss;
2684 dispc->dev = dev;
2685 dispc->feat = feat;
2686
2687 dispc_init_errata(dispc);
2688
2667 dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats),2689 dispc->fourccs = devm_kcalloc(dev, ARRAY_SIZE(dispc_color_formats),
2668 sizeof(*dispc->fourccs), GFP_KERNEL);2690 sizeof(*dispc->fourccs), GFP_KERNEL);
2669 if (!dispc->fourccs)2691 if (!dispc->fourccs)
2670 return -ENOMEM;2692 return -ENOMEM;
2671 2693
2672 num_fourccs = 0;2694 num_fourccs = 0;
2673 for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i)2695 for (i = 0; i < ARRAY_SIZE(dispc_color_formats); ++i) {
2696 if (dispc->errata.i2000 &&
2697 dispc_fourcc_is_yuv(dispc_color_formats[i].fourcc)) {
2698 continue;
2699 }
2674 dispc->fourccs[num_fourccs++] = dispc_color_formats[i].fourcc;2700 dispc->fourccs[num_fourccs++] = dispc_color_formats[i].fourcc;
2701 }
2675 2702
2676 dispc->num_fourccs = num_fourccs;2703 dispc->num_fourccs = num_fourccs;
2677 dispc->tidss = tidss;
2678 dispc->dev = dev;
2679 dispc->feat = feat;
2680 2704
2681 dispc_common_regmap = dispc->feat->common_regs;2705 dispc_common_regmap = dispc->feat->common_regs;
2682 2706
drivers/gpu/drm/tidss/tidss_dispc.h+4−0
@@ -46,6 +46,10 @@ struct dispc_features_scaling { · 45 unmodified lines
46 u32 xinc_max;46 u32 xinc_max;
47};47};
48 48
49struct dispc_errata {
50 bool i2000; /* DSS Does Not Support YUV Pixel Data Formats */
51};
52
49enum dispc_vp_bus_type {53enum dispc_vp_bus_type {
50 DISPC_VP_DPI, /* DPI output */54 DISPC_VP_DPI, /* DPI output */
51 DISPC_VP_OLDI, /* OLDI (LVDS) output */55 DISPC_VP_OLDI, /* OLDI (LVDS) output */
drivers/gpu/drm/ttm/Makefile+2−1
@@ -4,7 +4,8 @@ · 3 unmodified lines
4 4
5ttm-y := ttm_memory.o ttm_tt.o ttm_bo.o \5ttm-y := ttm_memory.o ttm_tt.o ttm_bo.o \
6 ttm_bo_util.o ttm_bo_vm.o ttm_module.o \6 ttm_bo_util.o ttm_bo_vm.o ttm_module.o \
7 ttm_execbuf_util.o ttm_page_alloc.o ttm_bo_manager.o7 ttm_execbuf_util.o ttm_page_alloc.o ttm_range_manager.o \
8 ttm_resource.o
8ttm-$(CONFIG_AGP) += ttm_agp_backend.o9ttm-$(CONFIG_AGP) += ttm_agp_backend.o
9ttm-$(CONFIG_DRM_TTM_DMA_PAGE_POOL) += ttm_page_alloc_dma.o10ttm-$(CONFIG_DRM_TTM_DMA_PAGE_POOL) += ttm_page_alloc_dma.o
10 11
drivers/gpu/drm/ttm/ttm_agp_backend.c+1−1
@@ -48,7 +48,7 @@ struct ttm_agp_backend { · 47 unmodified lines
48 struct agp_bridge_data *bridge;48 struct agp_bridge_data *bridge;
49};49};
50 50
51static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem)51static int ttm_agp_bind(struct ttm_tt *ttm, struct ttm_resource *bo_mem)
52{52{
53 struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);53 struct ttm_agp_backend *agp_be = container_of(ttm, struct ttm_agp_backend, ttm);
54 struct page *dummy_read_page = ttm_bo_glob.dummy_read_page;54 struct page *dummy_read_page = ttm_bo_glob.dummy_read_page;
drivers/gpu/drm/ttm/ttm_bo.c+89−258
@@ -77,26 +77,12 @@ static inline int ttm_mem_type_from_place(const struct ttm_place *place, · 76 unmodified lines
77 return 0;77 return 0;
78}78}
79 79
80static void ttm_mem_type_debug(struct ttm_bo_device *bdev, struct drm_printer *p,
81 int mem_type)
82{
83 struct ttm_mem_type_manager *man = &bdev->man[mem_type];
84
85 drm_printf(p, " has_type: %d\n", man->has_type);
86 drm_printf(p, " use_type: %d\n", man->use_type);
87 drm_printf(p, " flags: 0x%08X\n", man->flags);
88 drm_printf(p, " size: %llu\n", man->size);
89 drm_printf(p, " available_caching: 0x%08X\n", man->available_caching);
90 drm_printf(p, " default_caching: 0x%08X\n", man->default_caching);
91 if (mem_type != TTM_PL_SYSTEM)
92 (*man->func->debug)(man, p);
93}
94
95static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,80static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo,
96 struct ttm_placement *placement)81 struct ttm_placement *placement)
97{82{
98 struct drm_printer p = drm_debug_printer(TTM_PFX);83 struct drm_printer p = drm_debug_printer(TTM_PFX);
99 int i, ret, mem_type;84 int i, ret, mem_type;
85 struct ttm_resource_manager *man;
100 86
101 drm_printf(&p, "No space for %p (%lu pages, %luK, %luM)\n",87 drm_printf(&p, "No space for %p (%lu pages, %luK, %luM)\n",
102 bo, bo->mem.num_pages, bo->mem.size >> 10,88 bo, bo->mem.num_pages, bo->mem.size >> 10,
@@ -108,7 +94,8 @@ static void ttm_bo_mem_space_debug(struct ttm_buffer_object *bo, · 5 unmodified lines
108 return;94 return;
109 drm_printf(&p, " placement[%d]=0x%08X (%d)\n",95 drm_printf(&p, " placement[%d]=0x%08X (%d)\n",
110 i, placement->placement[i].flags, mem_type);96 i, placement->placement[i].flags, mem_type);
111 ttm_mem_type_debug(bo->bdev, &p, mem_type);97 man = ttm_manager_type(bo->bdev, mem_type);
98 ttm_resource_manager_debug(man, &p);
112 }99 }
113}100}
114 101
@@ -145,10 +132,10 @@ static inline uint32_t ttm_bo_type_flags(unsigned type) · 30 unmodified lines
145}132}
146 133
147static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo,134static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo,
148 struct ttm_mem_reg *mem)135 struct ttm_resource *mem)
149{136{
150 struct ttm_bo_device *bdev = bo->bdev;137 struct ttm_bo_device *bdev = bo->bdev;
151 struct ttm_mem_type_manager *man;138 struct ttm_resource_manager *man;
152 139
153 if (!list_empty(&bo->lru))140 if (!list_empty(&bo->lru))
154 return;141 return;
@@ -156,10 +143,10 @@ static void ttm_bo_add_mem_to_lru(struct ttm_buffer_object *bo, · 1 unmodified line
156 if (mem->placement & TTM_PL_FLAG_NO_EVICT)143 if (mem->placement & TTM_PL_FLAG_NO_EVICT)
157 return;144 return;
158 145
159 man = &bdev->man[mem->mem_type];146 man = ttm_manager_type(bdev, mem->mem_type);
160 list_add_tail(&bo->lru, &man->lru[bo->priority]);147 list_add_tail(&bo->lru, &man->lru[bo->priority]);
161 148
162 if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED) && bo->ttm &&149 if (man->use_tt && bo->ttm &&
163 !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG |150 !(bo->ttm->page_flags & (TTM_PAGE_FLAG_SG |
164 TTM_PAGE_FLAG_SWAPPED))) {151 TTM_PAGE_FLAG_SWAPPED))) {
165 list_add_tail(&bo->swap, &ttm_bo_glob.swap_lru[bo->priority]);152 list_add_tail(&bo->swap, &ttm_bo_glob.swap_lru[bo->priority]);
@@ -223,7 +210,7 @@ void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk) · 57 unmodified lines
223 210
224 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {211 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
225 struct ttm_lru_bulk_move_pos *pos = &bulk->tt[i];212 struct ttm_lru_bulk_move_pos *pos = &bulk->tt[i];
226 struct ttm_mem_type_manager *man;213 struct ttm_resource_manager *man;
227 214
228 if (!pos->first)215 if (!pos->first)
229 continue;216 continue;
@@ -231,14 +218,14 @@ void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk) · 1 unmodified line
231 dma_resv_assert_held(pos->first->base.resv);218 dma_resv_assert_held(pos->first->base.resv);
232 dma_resv_assert_held(pos->last->base.resv);219 dma_resv_assert_held(pos->last->base.resv);
233 220
234 man = &pos->first->bdev->man[TTM_PL_TT];221 man = ttm_manager_type(pos->first->bdev, TTM_PL_TT);
235 list_bulk_move_tail(&man->lru[i], &pos->first->lru,222 list_bulk_move_tail(&man->lru[i], &pos->first->lru,
236 &pos->last->lru);223 &pos->last->lru);
237 }224 }
238 225
239 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {226 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
240 struct ttm_lru_bulk_move_pos *pos = &bulk->vram[i];227 struct ttm_lru_bulk_move_pos *pos = &bulk->vram[i];
241 struct ttm_mem_type_manager *man;228 struct ttm_resource_manager *man;
242 229
243 if (!pos->first)230 if (!pos->first)
244 continue;231 continue;
@@ -246,7 +233,7 @@ void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk) · 1 unmodified line
246 dma_resv_assert_held(pos->first->base.resv);233 dma_resv_assert_held(pos->first->base.resv);
247 dma_resv_assert_held(pos->last->base.resv);234 dma_resv_assert_held(pos->last->base.resv);
248 235
249 man = &pos->first->bdev->man[TTM_PL_VRAM];236 man = ttm_manager_type(pos->first->bdev, TTM_PL_VRAM);
250 list_bulk_move_tail(&man->lru[i], &pos->first->lru,237 list_bulk_move_tail(&man->lru[i], &pos->first->lru,
251 &pos->last->lru);238 &pos->last->lru);
252 }239 }
@@ -268,12 +255,12 @@ void ttm_bo_bulk_move_lru_tail(struct ttm_lru_bulk_move *bulk) · 15 unmodified lines
268EXPORT_SYMBOL(ttm_bo_bulk_move_lru_tail);255EXPORT_SYMBOL(ttm_bo_bulk_move_lru_tail);
269 256
270static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,257static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo,
271 struct ttm_mem_reg *mem, bool evict,258 struct ttm_resource *mem, bool evict,
272 struct ttm_operation_ctx *ctx)259 struct ttm_operation_ctx *ctx)
273{260{
274 struct ttm_bo_device *bdev = bo->bdev;261 struct ttm_bo_device *bdev = bo->bdev;
275 struct ttm_mem_type_manager *old_man = &bdev->man[bo->mem.mem_type];262 struct ttm_resource_manager *old_man = ttm_manager_type(bdev, bo->mem.mem_type);
276 struct ttm_mem_type_manager *new_man = &bdev->man[mem->mem_type];263 struct ttm_resource_manager *new_man = ttm_manager_type(bdev, mem->mem_type);
277 int ret;264 int ret;
278 265
279 ret = ttm_mem_io_lock(old_man, true);266 ret = ttm_mem_io_lock(old_man, true);
@@ -286,13 +273,13 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, · 6 unmodified lines
286 * Create and bind a ttm if required.273 * Create and bind a ttm if required.
287 */274 */
288 275
289 if (!(new_man->flags & TTM_MEMTYPE_FLAG_FIXED)) {276 if (new_man->use_tt) {
290 if (bo->ttm == NULL) {277 /* Zero init the new TTM structure if the old location should
291 bool zero = !(old_man->flags & TTM_MEMTYPE_FLAG_FIXED);278 * have used one as well.
292 ret = ttm_tt_create(bo, zero);279 */
293 if (ret)280 ret = ttm_tt_create(bo, old_man->use_tt);
294 goto out_err;281 if (ret)
295 }282 goto out_err;
296 283
297 ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);284 ret = ttm_tt_set_placement_caching(bo->ttm, mem->placement);
298 if (ret)285 if (ret)
@@ -315,8 +302,7 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, · 16 unmodified lines
315 if (bdev->driver->move_notify)302 if (bdev->driver->move_notify)
316 bdev->driver->move_notify(bo, evict, mem);303 bdev->driver->move_notify(bo, evict, mem);
317 304
318 if (!(old_man->flags & TTM_MEMTYPE_FLAG_FIXED) &&305 if (old_man->use_tt && new_man->use_tt)
319 !(new_man->flags & TTM_MEMTYPE_FLAG_FIXED))
320 ret = ttm_bo_move_ttm(bo, ctx, mem);306 ret = ttm_bo_move_ttm(bo, ctx, mem);
321 else if (bdev->driver->move)307 else if (bdev->driver->move)
322 ret = bdev->driver->move(bo, evict, ctx, mem);308 ret = bdev->driver->move(bo, evict, ctx, mem);
@@ -340,8 +326,8 @@ moved: · 17 unmodified lines
340 return 0;326 return 0;
341 327
342out_err:328out_err:
343 new_man = &bdev->man[bo->mem.mem_type];329 new_man = ttm_manager_type(bdev, bo->mem.mem_type);
344 if (new_man->flags & TTM_MEMTYPE_FLAG_FIXED) {330 if (!new_man->use_tt) {
345 ttm_tt_destroy(bo->ttm);331 ttm_tt_destroy(bo->ttm);
346 bo->ttm = NULL;332 bo->ttm = NULL;
347 }333 }
@@ -364,7 +350,7 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) · 16 unmodified lines
364 350
365 ttm_tt_destroy(bo->ttm);351 ttm_tt_destroy(bo->ttm);
366 bo->ttm = NULL;352 bo->ttm = NULL;
367 ttm_bo_mem_put(bo, &bo->mem);353 ttm_resource_free(bo, &bo->mem);
368}354}
369 355
370static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)356static int ttm_bo_individualize_resv(struct ttm_buffer_object *bo)
@@ -552,7 +538,7 @@ static void ttm_bo_release(struct kref *kref) · 181 unmodified lines
552 struct ttm_buffer_object *bo =538 struct ttm_buffer_object *bo =
553 container_of(kref, struct ttm_buffer_object, kref);539 container_of(kref, struct ttm_buffer_object, kref);
554 struct ttm_bo_device *bdev = bo->bdev;540 struct ttm_bo_device *bdev = bo->bdev;
555 struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];541 struct ttm_resource_manager *man = ttm_manager_type(bdev, bo->mem.mem_type);
556 size_t acc_size = bo->acc_size;542 size_t acc_size = bo->acc_size;
557 int ret;543 int ret;
558 544
@@ -643,7 +629,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, · 84 unmodified lines
643 struct ttm_operation_ctx *ctx)629 struct ttm_operation_ctx *ctx)
644{630{
645 struct ttm_bo_device *bdev = bo->bdev;631 struct ttm_bo_device *bdev = bo->bdev;
646 struct ttm_mem_reg evict_mem;632 struct ttm_resource evict_mem;
647 struct ttm_placement placement;633 struct ttm_placement placement;
648 int ret = 0;634 int ret = 0;
649 635
@@ -654,10 +640,9 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, · 4 unmodified lines
654 bdev->driver->evict_flags(bo, &placement);640 bdev->driver->evict_flags(bo, &placement);
655 641
656 if (!placement.num_placement && !placement.num_busy_placement) {642 if (!placement.num_placement && !placement.num_busy_placement) {
657 ret = ttm_bo_pipeline_gutting(bo);643 ttm_bo_wait(bo, false, false);
658 if (ret)
659 return ret;
660 644
645 ttm_bo_cleanup_memtype_use(bo);
661 return ttm_tt_create(bo, false);646 return ttm_tt_create(bo, false);
662 }647 }
663 648
@@ -680,7 +665,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, · 16 unmodified lines
680 if (unlikely(ret)) {665 if (unlikely(ret)) {
681 if (ret != -ERESTARTSYS)666 if (ret != -ERESTARTSYS)
682 pr_err("Buffer eviction failed\n");667 pr_err("Buffer eviction failed\n");
683 ttm_bo_mem_put(bo, &evict_mem);668 ttm_resource_free(bo, &evict_mem);
684 goto out;669 goto out;
685 }670 }
686 bo->evicted = true;671 bo->evicted = true;
@@ -769,14 +754,13 @@ static int ttm_mem_evict_wait_busy(struct ttm_buffer_object *busy_bo, · 82 unmodified lines
769 return r == -EDEADLK ? -EBUSY : r;754 return r == -EDEADLK ? -EBUSY : r;
770}755}
771 756
772static int ttm_mem_evict_first(struct ttm_bo_device *bdev,757int ttm_mem_evict_first(struct ttm_bo_device *bdev,
773 uint32_t mem_type,758 struct ttm_resource_manager *man,
774 const struct ttm_place *place,759 const struct ttm_place *place,
775 struct ttm_operation_ctx *ctx,760 struct ttm_operation_ctx *ctx,
776 struct ww_acquire_ctx *ticket)761 struct ww_acquire_ctx *ticket)
777{762{
778 struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;763 struct ttm_buffer_object *bo = NULL, *busy_bo = NULL;
779 struct ttm_mem_type_manager *man = &bdev->man[mem_type];
780 bool locked = false;764 bool locked = false;
781 unsigned i;765 unsigned i;
782 int ret;766 int ret;
@@ -842,38 +826,12 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, · 59 unmodified lines
842 return ret;826 return ret;
843}827}
844 828
845static int ttm_bo_mem_get(struct ttm_buffer_object *bo,
846 const struct ttm_place *place,
847 struct ttm_mem_reg *mem)
848{
849 struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type];
850
851 mem->mm_node = NULL;
852 if (!man->func || !man->func->get_node)
853 return 0;
854
855 return man->func->get_node(man, bo, place, mem);
856}
857
858void ttm_bo_mem_put(struct ttm_buffer_object *bo, struct ttm_mem_reg *mem)
859{
860 struct ttm_mem_type_manager *man = &bo->bdev->man[mem->mem_type];
861
862 if (!man->func || !man->func->put_node)
863 return;
864
865 man->func->put_node(man, mem);
866 mem->mm_node = NULL;
867 mem->mem_type = TTM_PL_SYSTEM;
868}
869EXPORT_SYMBOL(ttm_bo_mem_put);
870
871/**829/**
872 * Add the last move fence to the BO and reserve a new shared slot.830 * Add the last move fence to the BO and reserve a new shared slot.
873 */831 */
874static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,832static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo,
875 struct ttm_mem_type_manager *man,833 struct ttm_resource_manager *man,
876 struct ttm_mem_reg *mem,834 struct ttm_resource *mem,
877 bool no_wait_gpu)835 bool no_wait_gpu)
878{836{
879 struct dma_fence *fence;837 struct dma_fence *fence;
@@ -910,22 +868,22 @@ static int ttm_bo_add_move_fence(struct ttm_buffer_object *bo, · 30 unmodified lines
910 */868 */
911static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,869static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo,
912 const struct ttm_place *place,870 const struct ttm_place *place,
913 struct ttm_mem_reg *mem,871 struct ttm_resource *mem,
914 struct ttm_operation_ctx *ctx)872 struct ttm_operation_ctx *ctx)
915{873{
916 struct ttm_bo_device *bdev = bo->bdev;874 struct ttm_bo_device *bdev = bo->bdev;
917 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];875 struct ttm_resource_manager *man = ttm_manager_type(bdev, mem->mem_type);
918 struct ww_acquire_ctx *ticket;876 struct ww_acquire_ctx *ticket;
919 int ret;877 int ret;
920 878
921 ticket = dma_resv_locking_ctx(bo->base.resv);879 ticket = dma_resv_locking_ctx(bo->base.resv);
922 do {880 do {
923 ret = ttm_bo_mem_get(bo, place, mem);881 ret = ttm_resource_alloc(bo, place, mem);
924 if (likely(!ret))882 if (likely(!ret))
925 break;883 break;
926 if (unlikely(ret != -ENOSPC))884 if (unlikely(ret != -ENOSPC))
927 return ret;885 return ret;
928 ret = ttm_mem_evict_first(bdev, mem->mem_type, place, ctx,886 ret = ttm_mem_evict_first(bdev, man, place, ctx,
929 ticket);887 ticket);
930 if (unlikely(ret != 0))888 if (unlikely(ret != 0))
931 return ret;889 return ret;
@@ -934,7 +892,7 @@ static int ttm_bo_mem_force_space(struct ttm_buffer_object *bo, · 2 unmodified lines
934 return ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);892 return ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
935}893}
936 894
937static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man,895static uint32_t ttm_bo_select_caching(struct ttm_resource_manager *man,
938 uint32_t cur_placement,896 uint32_t cur_placement,
939 uint32_t proposed_placement)897 uint32_t proposed_placement)
940{898{
@@ -959,7 +917,7 @@ static uint32_t ttm_bo_select_caching(struct ttm_mem_type_manager *man, · 18 unmodified lines
959 return result;917 return result;
960}918}
961 919
962static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man,920static bool ttm_bo_mt_compatible(struct ttm_resource_manager *man,
963 uint32_t mem_type,921 uint32_t mem_type,
964 const struct ttm_place *place,922 const struct ttm_place *place,
965 uint32_t *masked_placement)923 uint32_t *masked_placement)
@@ -991,12 +949,12 @@ static bool ttm_bo_mt_compatible(struct ttm_mem_type_manager *man, · 25 unmodified lines
991 */949 */
992static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,950static int ttm_bo_mem_placement(struct ttm_buffer_object *bo,
993 const struct ttm_place *place,951 const struct ttm_place *place,
994 struct ttm_mem_reg *mem,952 struct ttm_resource *mem,
995 struct ttm_operation_ctx *ctx)953 struct ttm_operation_ctx *ctx)
996{954{
997 struct ttm_bo_device *bdev = bo->bdev;955 struct ttm_bo_device *bdev = bo->bdev;
998 uint32_t mem_type = TTM_PL_SYSTEM;956 uint32_t mem_type = TTM_PL_SYSTEM;
999 struct ttm_mem_type_manager *man;957 struct ttm_resource_manager *man;
1000 uint32_t cur_flags = 0;958 uint32_t cur_flags = 0;
1001 int ret;959 int ret;
1002 960
@@ -1004,8 +962,8 @@ static int ttm_bo_mem_placement(struct ttm_buffer_object *bo, · 1 unmodified line
1004 if (ret)962 if (ret)
1005 return ret;963 return ret;
1006 964
1007 man = &bdev->man[mem_type];965 man = ttm_manager_type(bdev, mem_type);
1008 if (!man->has_type || !man->use_type)966 if (!man || !ttm_resource_manager_used(man))
1009 return -EBUSY;967 return -EBUSY;
1010 968
1011 if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))969 if (!ttm_bo_mt_compatible(man, mem_type, place, &cur_flags))
@@ -1039,7 +997,7 @@ static int ttm_bo_mem_placement(struct ttm_buffer_object *bo, · 27 unmodified lines
1039 */997 */
1040int ttm_bo_mem_space(struct ttm_buffer_object *bo,998int ttm_bo_mem_space(struct ttm_buffer_object *bo,
1041 struct ttm_placement *placement,999 struct ttm_placement *placement,
1042 struct ttm_mem_reg *mem,1000 struct ttm_resource *mem,
1043 struct ttm_operation_ctx *ctx)1001 struct ttm_operation_ctx *ctx)
1044{1002{
1045 struct ttm_bo_device *bdev = bo->bdev;1003 struct ttm_bo_device *bdev = bo->bdev;
@@ -1052,7 +1010,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, · 6 unmodified lines
1052 1010
1053 for (i = 0; i < placement->num_placement; ++i) {1011 for (i = 0; i < placement->num_placement; ++i) {
1054 const struct ttm_place *place = &placement->placement[i];1012 const struct ttm_place *place = &placement->placement[i];
1055 struct ttm_mem_type_manager *man;1013 struct ttm_resource_manager *man;
1056 1014
1057 ret = ttm_bo_mem_placement(bo, place, mem, ctx);1015 ret = ttm_bo_mem_placement(bo, place, mem, ctx);
1058 if (ret == -EBUSY)1016 if (ret == -EBUSY)
@@ -1061,16 +1019,16 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, · 2 unmodified lines
1061 goto error;1019 goto error;
1062 1020
1063 type_found = true;1021 type_found = true;
1064 ret = ttm_bo_mem_get(bo, place, mem);1022 ret = ttm_resource_alloc(bo, place, mem);
1065 if (ret == -ENOSPC)1023 if (ret == -ENOSPC)
1066 continue;1024 continue;
1067 if (unlikely(ret))1025 if (unlikely(ret))
1068 goto error;1026 goto error;
1069 1027
1070 man = &bdev->man[mem->mem_type];1028 man = ttm_manager_type(bdev, mem->mem_type);
1071 ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);1029 ret = ttm_bo_add_move_fence(bo, man, mem, ctx->no_wait_gpu);
1072 if (unlikely(ret)) {1030 if (unlikely(ret)) {
1073 ttm_bo_mem_put(bo, mem);1031 ttm_resource_free(bo, mem);
1074 if (ret == -EBUSY)1032 if (ret == -EBUSY)
1075 continue;1033 continue;
1076 1034
@@ -1105,9 +1063,7 @@ int ttm_bo_mem_space(struct ttm_buffer_object *bo, · 28 unmodified lines
1105 1063
1106error:1064error:
1107 if (bo->mem.mem_type == TTM_PL_SYSTEM && !list_empty(&bo->lru)) {1065 if (bo->mem.mem_type == TTM_PL_SYSTEM && !list_empty(&bo->lru)) {
1108 spin_lock(&ttm_bo_glob.lru_lock);1066 ttm_bo_move_to_lru_tail_unlocked(bo);
1109 ttm_bo_move_to_lru_tail(bo, NULL);
1110 spin_unlock(&ttm_bo_glob.lru_lock);
1111 }1067 }
1112 1068
1113 return ret;1069 return ret;
@@ -1119,7 +1075,7 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, · 5 unmodified lines
1119 struct ttm_operation_ctx *ctx)1075 struct ttm_operation_ctx *ctx)
1120{1076{
1121 int ret = 0;1077 int ret = 0;
1122 struct ttm_mem_reg mem;1078 struct ttm_resource mem;
1123 1079
1124 dma_resv_assert_held(bo->base.resv);1080 dma_resv_assert_held(bo->base.resv);
1125 1081
@@ -1139,13 +1095,13 @@ static int ttm_bo_move_buffer(struct ttm_buffer_object *bo, · 13 unmodified lines
1139 ret = ttm_bo_handle_move_mem(bo, &mem, false, ctx);1095 ret = ttm_bo_handle_move_mem(bo, &mem, false, ctx);
1140out_unlock:1096out_unlock:
1141 if (ret)1097 if (ret)
1142 ttm_bo_mem_put(bo, &mem);1098 ttm_resource_free(bo, &mem);
1143 return ret;1099 return ret;
1144}1100}
1145 1101
1146static bool ttm_bo_places_compat(const struct ttm_place *places,1102static bool ttm_bo_places_compat(const struct ttm_place *places,
1147 unsigned num_placement,1103 unsigned num_placement,
1148 struct ttm_mem_reg *mem,1104 struct ttm_resource *mem,
1149 uint32_t *new_flags)1105 uint32_t *new_flags)
1150{1106{
1151 unsigned i;1107 unsigned i;
@@ -1168,7 +1124,7 @@ static bool ttm_bo_places_compat(const struct ttm_place *places, · 16 unmodified lines
1168}1124}
1169 1125
1170bool ttm_bo_mem_compat(struct ttm_placement *placement,1126bool ttm_bo_mem_compat(struct ttm_placement *placement,
1171 struct ttm_mem_reg *mem,1127 struct ttm_resource *mem,
1172 uint32_t *new_flags)1128 uint32_t *new_flags)
1173{1129{
1174 if (ttm_bo_places_compat(placement->placement, placement->num_placement,1130 if (ttm_bo_places_compat(placement->placement, placement->num_placement,
@@ -1224,7 +1180,7 @@ int ttm_bo_validate(struct ttm_buffer_object *bo, · 49 unmodified lines
1224 /*1180 /*
1225 * We might need to add a TTM.1181 * We might need to add a TTM.
1226 */1182 */
1227 if (bo->mem.mem_type == TTM_PL_SYSTEM && bo->ttm == NULL) {1183 if (bo->mem.mem_type == TTM_PL_SYSTEM) {
1228 ret = ttm_tt_create(bo, true);1184 ret = ttm_tt_create(bo, true);
1229 if (ret)1185 if (ret)
1230 return ret;1186 return ret;
@@ -1335,9 +1291,7 @@ int ttm_bo_init_reserved(struct ttm_bo_device *bdev, · 104 unmodified lines
1335 return ret;1291 return ret;
1336 }1292 }
1337 1293
1338 spin_lock(&ttm_bo_glob.lru_lock);1294 ttm_bo_move_to_lru_tail_unlocked(bo);
1339 ttm_bo_move_to_lru_tail(bo, NULL);
1340 spin_unlock(&ttm_bo_glob.lru_lock);
1341 1295
1342 return ret;1296 return ret;
1343}1297}
@@ -1426,144 +1380,24 @@ int ttm_bo_create(struct ttm_bo_device *bdev, · 82 unmodified lines
1426}1380}
1427EXPORT_SYMBOL(ttm_bo_create);1381EXPORT_SYMBOL(ttm_bo_create);
1428 1382
1429static int ttm_bo_force_list_clean(struct ttm_bo_device *bdev,
1430 unsigned mem_type)
1431{
1432 struct ttm_operation_ctx ctx = {
1433 .interruptible = false,
1434 .no_wait_gpu = false,
1435 .flags = TTM_OPT_FLAG_FORCE_ALLOC
1436 };
1437 struct ttm_mem_type_manager *man = &bdev->man[mem_type];
1438 struct ttm_bo_global *glob = &ttm_bo_glob;
1439 struct dma_fence *fence;
1440 int ret;
1441 unsigned i;
1442
1443 /*
1444 * Can't use standard list traversal since we're unlocking.
1445 */
1446
1447 spin_lock(&glob->lru_lock);
1448 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
1449 while (!list_empty(&man->lru[i])) {
1450 spin_unlock(&glob->lru_lock);
1451 ret = ttm_mem_evict_first(bdev, mem_type, NULL, &ctx,
1452 NULL);
1453 if (ret)
1454 return ret;
1455 spin_lock(&glob->lru_lock);
1456 }
1457 }
1458 spin_unlock(&glob->lru_lock);
1459
1460 spin_lock(&man->move_lock);
1461 fence = dma_fence_get(man->move);
1462 spin_unlock(&man->move_lock);
1463
1464 if (fence) {
1465 ret = dma_fence_wait(fence, false);
1466 dma_fence_put(fence);
1467 if (ret)
1468 return ret;
1469 }
1470
1471 return 0;
1472}
1473
1474int ttm_bo_clean_mm(struct ttm_bo_device *bdev, unsigned mem_type)
1475{
1476 struct ttm_mem_type_manager *man;
1477 int ret = -EINVAL;
1478
1479 if (mem_type >= TTM_NUM_MEM_TYPES) {
1480 pr_err("Illegal memory type %d\n", mem_type);
1481 return ret;
1482 }
1483 man = &bdev->man[mem_type];
1484
1485 if (!man->has_type) {
1486 pr_err("Trying to take down uninitialized memory manager type %u\n",
1487 mem_type);
1488 return ret;
1489 }
1490
1491 man->use_type = false;
1492 man->has_type = false;
1493
1494 ret = 0;
1495 if (mem_type > 0) {
1496 ret = ttm_bo_force_list_clean(bdev, mem_type);
1497 if (ret) {
1498 pr_err("Cleanup eviction failed\n");
1499 return ret;
1500 }
1501
1502 ret = (*man->func->takedown)(man);
1503 }
1504
1505 dma_fence_put(man->move);
1506 man->move = NULL;
1507
1508 return ret;
1509}
1510EXPORT_SYMBOL(ttm_bo_clean_mm);
1511
1512int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)1383int ttm_bo_evict_mm(struct ttm_bo_device *bdev, unsigned mem_type)
1513{1384{
1514 struct ttm_mem_type_manager *man = &bdev->man[mem_type];1385 struct ttm_resource_manager *man = ttm_manager_type(bdev, mem_type);
1515 1386
1516 if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) {1387 if (mem_type == 0 || mem_type >= TTM_NUM_MEM_TYPES) {
1517 pr_err("Illegal memory manager memory type %u\n", mem_type);1388 pr_err("Illegal memory manager memory type %u\n", mem_type);
1518 return -EINVAL;1389 return -EINVAL;
1519 }1390 }
1520 1391
1521 if (!man->has_type) {1392 if (!man) {
1522 pr_err("Memory type %u has not been initialized\n", mem_type);1393 pr_err("Memory type %u has not been initialized\n", mem_type);
1523 return 0;1394 return 0;
1524 }1395 }
1525 1396
1526 return ttm_bo_force_list_clean(bdev, mem_type);1397 return ttm_resource_manager_force_list_clean(bdev, man);
1527}1398}
1528EXPORT_SYMBOL(ttm_bo_evict_mm);1399EXPORT_SYMBOL(ttm_bo_evict_mm);
1529 1400
1530int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type,
1531 unsigned long p_size)
1532{
1533 int ret;
1534 struct ttm_mem_type_manager *man;
1535 unsigned i;
1536
1537 BUG_ON(type >= TTM_NUM_MEM_TYPES);
1538 man = &bdev->man[type];
1539 BUG_ON(man->has_type);
1540 man->use_io_reserve_lru = false;
1541 mutex_init(&man->io_reserve_mutex);
1542 spin_lock_init(&man->move_lock);
1543 INIT_LIST_HEAD(&man->io_reserve_lru);
1544
1545 ret = bdev->driver->init_mem_type(bdev, type, man);
1546 if (ret)
1547 return ret;
1548 man->bdev = bdev;
1549
1550 if (type != TTM_PL_SYSTEM) {
1551 ret = (*man->func->init)(man, p_size);
1552 if (ret)
1553 return ret;
1554 }
1555 man->has_type = true;
1556 man->use_type = true;
1557 man->size = p_size;
1558
1559 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
1560 INIT_LIST_HEAD(&man->lru[i]);
1561 man->move = NULL;
1562
1563 return 0;
1564}
1565EXPORT_SYMBOL(ttm_bo_init_mm);
1566
1567static void ttm_bo_global_kobj_release(struct kobject *kobj)1401static void ttm_bo_global_kobj_release(struct kobject *kobj)
1568{1402{
1569 struct ttm_bo_global *glob =1403 struct ttm_bo_global *glob =
@@ -1628,21 +1462,12 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) · 58 unmodified lines
1628{1462{
1629 struct ttm_bo_global *glob = &ttm_bo_glob;1463 struct ttm_bo_global *glob = &ttm_bo_glob;
1630 int ret = 0;1464 int ret = 0;
1631 unsigned i = TTM_NUM_MEM_TYPES;1465 unsigned i;
1632 struct ttm_mem_type_manager *man;1466 struct ttm_resource_manager *man;
1633 1467
1634 while (i--) {1468 man = ttm_manager_type(bdev, TTM_PL_SYSTEM);
1635 man = &bdev->man[i];1469 ttm_resource_manager_set_used(man, false);
1636 if (man->has_type) {1470 ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, NULL);
1637 man->use_type = false;
1638 if ((i != TTM_PL_SYSTEM) && ttm_bo_clean_mm(bdev, i)) {
1639 ret = -EBUSY;
1640 pr_err("DRM memory manager type %d is not clean\n",
1641 i);
1642 }
1643 man->has_type = false;
1644 }
1645 }
1646 1471
1647 mutex_lock(&ttm_global_mutex);1472 mutex_lock(&ttm_global_mutex);
1648 list_del(&bdev->device_list);1473 list_del(&bdev->device_list);
@@ -1655,7 +1480,7 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) · 6 unmodified lines
1655 1480
1656 spin_lock(&glob->lru_lock);1481 spin_lock(&glob->lru_lock);
1657 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)1482 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
1658 if (list_empty(&bdev->man[0].lru[0]))1483 if (list_empty(&man->lru[0]))
1659 pr_debug("Swap list %d was clean\n", i);1484 pr_debug("Swap list %d was clean\n", i);
1660 spin_unlock(&glob->lru_lock);1485 spin_unlock(&glob->lru_lock);
1661 1486
@@ -1666,6 +1491,23 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) · 4 unmodified lines
1666}1491}
1667EXPORT_SYMBOL(ttm_bo_device_release);1492EXPORT_SYMBOL(ttm_bo_device_release);
1668 1493
1494static void ttm_bo_init_sysman(struct ttm_bo_device *bdev)
1495{
1496 struct ttm_resource_manager *man = &bdev->sysman;
1497
1498 /*
1499 * Initialize the system memory buffer type.
1500 * Other types need to be driver / IOCTL initialized.
1501 */
1502 man->use_tt = true;
1503 man->available_caching = TTM_PL_MASK_CACHING;
1504 man->default_caching = TTM_PL_FLAG_CACHED;
1505
1506 ttm_resource_manager_init(man, 0);
1507 ttm_set_driver_manager(bdev, TTM_PL_SYSTEM, man);
1508 ttm_resource_manager_set_used(man, true);
1509}
1510
1669int ttm_bo_device_init(struct ttm_bo_device *bdev,1511int ttm_bo_device_init(struct ttm_bo_device *bdev,
1670 struct ttm_bo_driver *driver,1512 struct ttm_bo_driver *driver,
1671 struct address_space *mapping,1513 struct address_space *mapping,
@@ -1684,15 +1526,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, · 12 unmodified lines
1684 1526
1685 bdev->driver = driver;1527 bdev->driver = driver;
1686 1528
1687 memset(bdev->man, 0, sizeof(bdev->man));1529 ttm_bo_init_sysman(bdev);
1688
1689 /*
1690 * Initialize the system memory buffer type.
1691 * Other types need to be driver / IOCTL initialized.
1692 */
1693 ret = ttm_bo_init_mm(bdev, TTM_PL_SYSTEM, 0);
1694 if (unlikely(ret != 0))
1695 goto out_no_sys;
1696 1530
1697 bdev->vma_manager = vma_manager;1531 bdev->vma_manager = vma_manager;
1698 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);1532 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue);
@@ -1704,9 +1538,6 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, · 5 unmodified lines
1704 mutex_unlock(&ttm_global_mutex);1538 mutex_unlock(&ttm_global_mutex);
1705 1539
1706 return 0;1540 return 0;
1707out_no_sys:
1708 ttm_bo_global_release();
1709 return ret;
1710}1541}
1711EXPORT_SYMBOL(ttm_bo_device_init);1542EXPORT_SYMBOL(ttm_bo_device_init);
1712 1543
@@ -1725,7 +1556,7 @@ void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo) · 12 unmodified lines
1725void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)1556void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo)
1726{1557{
1727 struct ttm_bo_device *bdev = bo->bdev;1558 struct ttm_bo_device *bdev = bo->bdev;
1728 struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type];1559 struct ttm_resource_manager *man = ttm_manager_type(bdev, bo->mem.mem_type);
1729 1560
1730 ttm_mem_io_lock(man, false);1561 ttm_mem_io_lock(man, false);
1731 ttm_bo_unmap_virtual_locked(bo);1562 ttm_bo_unmap_virtual_locked(bo);
@@ -1812,7 +1643,7 @@ int ttm_bo_swapout(struct ttm_bo_global *glob, struct ttm_operation_ctx *ctx) · 80 unmodified lines
1812 if (bo->mem.mem_type != TTM_PL_SYSTEM ||1643 if (bo->mem.mem_type != TTM_PL_SYSTEM ||
1813 bo->ttm->caching_state != tt_cached) {1644 bo->ttm->caching_state != tt_cached) {
1814 struct ttm_operation_ctx ctx = { false, false };1645 struct ttm_operation_ctx ctx = { false, false };
1815 struct ttm_mem_reg evict_mem;1646 struct ttm_resource evict_mem;
1816 1647
1817 evict_mem = bo->mem;1648 evict_mem = bo->mem;
1818 evict_mem.mm_node = NULL;1649 evict_mem.mm_node = NULL;
drivers/gpu/drm/ttm/ttm_bo_util.c+55−49
@@ -47,15 +47,15 @@ struct ttm_transfer_obj { · 46 unmodified lines
47 47
48void ttm_bo_free_old_node(struct ttm_buffer_object *bo)48void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
49{49{
50 ttm_bo_mem_put(bo, &bo->mem);50 ttm_resource_free(bo, &bo->mem);
51}51}
52 52
53int ttm_bo_move_ttm(struct ttm_buffer_object *bo,53int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
54 struct ttm_operation_ctx *ctx,54 struct ttm_operation_ctx *ctx,
55 struct ttm_mem_reg *new_mem)55 struct ttm_resource *new_mem)
56{56{
57 struct ttm_tt *ttm = bo->ttm;57 struct ttm_tt *ttm = bo->ttm;
58 struct ttm_mem_reg *old_mem = &bo->mem;58 struct ttm_resource *old_mem = &bo->mem;
59 int ret;59 int ret;
60 60
61 if (old_mem->mem_type != TTM_PL_SYSTEM) {61 if (old_mem->mem_type != TTM_PL_SYSTEM) {
@@ -91,7 +91,7 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, · 29 unmodified lines
91}91}
92EXPORT_SYMBOL(ttm_bo_move_ttm);92EXPORT_SYMBOL(ttm_bo_move_ttm);
93 93
94int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible)94int ttm_mem_io_lock(struct ttm_resource_manager *man, bool interruptible)
95{95{
96 if (likely(!man->use_io_reserve_lru))96 if (likely(!man->use_io_reserve_lru))
97 return 0;97 return 0;
@@ -103,7 +103,7 @@ int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible) · 5 unmodified lines
103 return 0;103 return 0;
104}104}
105 105
106void ttm_mem_io_unlock(struct ttm_mem_type_manager *man)106void ttm_mem_io_unlock(struct ttm_resource_manager *man)
107{107{
108 if (likely(!man->use_io_reserve_lru))108 if (likely(!man->use_io_reserve_lru))
109 return;109 return;
@@ -111,7 +111,7 @@ void ttm_mem_io_unlock(struct ttm_mem_type_manager *man) · 1 unmodified line
111 mutex_unlock(&man->io_reserve_mutex);111 mutex_unlock(&man->io_reserve_mutex);
112}112}
113 113
114static int ttm_mem_io_evict(struct ttm_mem_type_manager *man)114static int ttm_mem_io_evict(struct ttm_resource_manager *man)
115{115{
116 struct ttm_buffer_object *bo;116 struct ttm_buffer_object *bo;
117 117
@@ -127,9 +127,9 @@ static int ttm_mem_io_evict(struct ttm_mem_type_manager *man) · 9 unmodified lines
127}127}
128 128
129int ttm_mem_io_reserve(struct ttm_bo_device *bdev,129int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
130 struct ttm_mem_reg *mem)130 struct ttm_resource *mem)
131{131{
132 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];132 struct ttm_resource_manager *man = ttm_manager_type(bdev, mem->mem_type);
133 int ret;133 int ret;
134 134
135 if (mem->bus.io_reserved_count++)135 if (mem->bus.io_reserved_count++)
@@ -138,6 +138,10 @@ int ttm_mem_io_reserve(struct ttm_bo_device *bdev, · 2 unmodified lines
138 if (!bdev->driver->io_mem_reserve)138 if (!bdev->driver->io_mem_reserve)
139 return 0;139 return 0;
140 140
141 mem->bus.addr = NULL;
142 mem->bus.offset = 0;
143 mem->bus.base = 0;
144 mem->bus.is_iomem = false;
141retry:145retry:
142 ret = bdev->driver->io_mem_reserve(bdev, mem);146 ret = bdev->driver->io_mem_reserve(bdev, mem);
143 if (ret == -ENOSPC) {147 if (ret == -ENOSPC) {
@@ -149,7 +153,7 @@ retry: · 5 unmodified lines
149}153}
150 154
151void ttm_mem_io_free(struct ttm_bo_device *bdev,155void ttm_mem_io_free(struct ttm_bo_device *bdev,
152 struct ttm_mem_reg *mem)156 struct ttm_resource *mem)
153{157{
154 if (--mem->bus.io_reserved_count)158 if (--mem->bus.io_reserved_count)
155 return;159 return;
@@ -162,8 +166,8 @@ void ttm_mem_io_free(struct ttm_bo_device *bdev, · 6 unmodified lines
162 166
163int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo)167int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo)
164{168{
165 struct ttm_mem_type_manager *man = &bo->bdev->man[bo->mem.mem_type];169 struct ttm_resource_manager *man = ttm_manager_type(bo->bdev, bo->mem.mem_type);
166 struct ttm_mem_reg *mem = &bo->mem;170 struct ttm_resource *mem = &bo->mem;
167 int ret;171 int ret;
168 172
169 if (mem->bus.io_reserved_vm)173 if (mem->bus.io_reserved_vm)
@@ -181,7 +185,7 @@ int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo) · 11 unmodified lines
181 185
182void ttm_mem_io_free_vm(struct ttm_buffer_object *bo)186void ttm_mem_io_free_vm(struct ttm_buffer_object *bo)
183{187{
184 struct ttm_mem_reg *mem = &bo->mem;188 struct ttm_resource *mem = &bo->mem;
185 189
186 if (!mem->bus.io_reserved_vm)190 if (!mem->bus.io_reserved_vm)
187 return;191 return;
@@ -191,11 +195,11 @@ void ttm_mem_io_free_vm(struct ttm_buffer_object *bo) · 3 unmodified lines
191 ttm_mem_io_free(bo->bdev, mem);195 ttm_mem_io_free(bo->bdev, mem);
192}196}
193 197
194static int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev,198static int ttm_resource_ioremap(struct ttm_bo_device *bdev,
195 struct ttm_mem_reg *mem,199 struct ttm_resource *mem,
196 void **virtual)200 void **virtual)
197{201{
198 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];202 struct ttm_resource_manager *man = ttm_manager_type(bdev, mem->mem_type);
199 int ret;203 int ret;
200 void *addr;204 void *addr;
201 205
@@ -209,12 +213,14 @@ static int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, · 7 unmodified lines
209 if (mem->bus.addr) {213 if (mem->bus.addr) {
210 addr = mem->bus.addr;214 addr = mem->bus.addr;
211 } else {215 } else {
216 size_t bus_size = (size_t)mem->num_pages << PAGE_SHIFT;
217
212 if (mem->placement & TTM_PL_FLAG_WC)218 if (mem->placement & TTM_PL_FLAG_WC)
213 addr = ioremap_wc(mem->bus.base + mem->bus.offset,219 addr = ioremap_wc(mem->bus.base + mem->bus.offset,
214 mem->bus.size);220 bus_size);
215 else221 else
216 addr = ioremap(mem->bus.base + mem->bus.offset,222 addr = ioremap(mem->bus.base + mem->bus.offset,
217 mem->bus.size);223 bus_size);
218 if (!addr) {224 if (!addr) {
219 (void) ttm_mem_io_lock(man, false);225 (void) ttm_mem_io_lock(man, false);
220 ttm_mem_io_free(bdev, mem);226 ttm_mem_io_free(bdev, mem);
@@ -226,13 +232,13 @@ static int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, · 5 unmodified lines
226 return 0;232 return 0;
227}233}
228 234
229static void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev,235static void ttm_resource_iounmap(struct ttm_bo_device *bdev,
230 struct ttm_mem_reg *mem,236 struct ttm_resource *mem,
231 void *virtual)237 void *virtual)
232{238{
233 struct ttm_mem_type_manager *man;239 struct ttm_resource_manager *man;
234 240
235 man = &bdev->man[mem->mem_type];241 man = ttm_manager_type(bdev, mem->mem_type);
236 242
237 if (virtual && mem->bus.addr == NULL)243 if (virtual && mem->bus.addr == NULL)
238 iounmap(virtual);244 iounmap(virtual);
@@ -300,13 +306,13 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, · 61 unmodified lines
300 306
301int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,307int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
302 struct ttm_operation_ctx *ctx,308 struct ttm_operation_ctx *ctx,
303 struct ttm_mem_reg *new_mem)309 struct ttm_resource *new_mem)
304{310{
305 struct ttm_bo_device *bdev = bo->bdev;311 struct ttm_bo_device *bdev = bo->bdev;
306 struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];312 struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
307 struct ttm_tt *ttm = bo->ttm;313 struct ttm_tt *ttm = bo->ttm;
308 struct ttm_mem_reg *old_mem = &bo->mem;314 struct ttm_resource *old_mem = &bo->mem;
309 struct ttm_mem_reg old_copy = *old_mem;315 struct ttm_resource old_copy = *old_mem;
310 void *old_iomap;316 void *old_iomap;
311 void *new_iomap;317 void *new_iomap;
312 int ret;318 int ret;
@@ -319,10 +325,10 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, · 6 unmodified lines
319 if (ret)325 if (ret)
320 return ret;326 return ret;
321 327
322 ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);328 ret = ttm_resource_ioremap(bdev, old_mem, &old_iomap);
323 if (ret)329 if (ret)
324 return ret;330 return ret;
325 ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);331 ret = ttm_resource_ioremap(bdev, new_mem, &new_iomap);
326 if (ret)332 if (ret)
327 goto out;333 goto out;
328 334
@@ -384,21 +390,21 @@ out2: · 55 unmodified lines
384 *old_mem = *new_mem;390 *old_mem = *new_mem;
385 new_mem->mm_node = NULL;391 new_mem->mm_node = NULL;
386 392
387 if (man->flags & TTM_MEMTYPE_FLAG_FIXED) {393 if (!man->use_tt) {
388 ttm_tt_destroy(ttm);394 ttm_tt_destroy(ttm);
389 bo->ttm = NULL;395 bo->ttm = NULL;
390 }396 }
391 397
392out1:398out1:
393 ttm_mem_reg_iounmap(bdev, old_mem, new_iomap);399 ttm_resource_iounmap(bdev, old_mem, new_iomap);
394out:400out:
395 ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);401 ttm_resource_iounmap(bdev, &old_copy, old_iomap);
396 402
397 /*403 /*
398 * On error, keep the mm node!404 * On error, keep the mm node!
399 */405 */
400 if (!ret)406 if (!ret)
401 ttm_bo_mem_put(bo, &old_copy);407 ttm_resource_free(bo, &old_copy);
402 return ret;408 return ret;
403}409}
404EXPORT_SYMBOL(ttm_bo_move_memcpy);410EXPORT_SYMBOL(ttm_bo_move_memcpy);
@@ -502,7 +508,7 @@ static int ttm_bo_ioremap(struct ttm_buffer_object *bo, · 97 unmodified lines
502 unsigned long size,508 unsigned long size,
503 struct ttm_bo_kmap_obj *map)509 struct ttm_bo_kmap_obj *map)
504{510{
505 struct ttm_mem_reg *mem = &bo->mem;511 struct ttm_resource *mem = &bo->mem;
506 512
507 if (bo->mem.bus.addr) {513 if (bo->mem.bus.addr) {
508 map->bo_kmap_type = ttm_bo_map_premapped;514 map->bo_kmap_type = ttm_bo_map_premapped;
@@ -526,7 +532,7 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, · 17 unmodified lines
526 unsigned long num_pages,532 unsigned long num_pages,
527 struct ttm_bo_kmap_obj *map)533 struct ttm_bo_kmap_obj *map)
528{534{
529 struct ttm_mem_reg *mem = &bo->mem;535 struct ttm_resource *mem = &bo->mem;
530 struct ttm_operation_ctx ctx = {536 struct ttm_operation_ctx ctx = {
531 .interruptible = false,537 .interruptible = false,
532 .no_wait_gpu = false538 .no_wait_gpu = false
@@ -567,8 +573,8 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, · 34 unmodified lines
567 unsigned long start_page, unsigned long num_pages,573 unsigned long start_page, unsigned long num_pages,
568 struct ttm_bo_kmap_obj *map)574 struct ttm_bo_kmap_obj *map)
569{575{
570 struct ttm_mem_type_manager *man =576 struct ttm_resource_manager *man =
571 &bo->bdev->man[bo->mem.mem_type];577 ttm_manager_type(bo->bdev, bo->mem.mem_type);
572 unsigned long offset, size;578 unsigned long offset, size;
573 int ret;579 int ret;
574 580
@@ -597,8 +603,8 @@ EXPORT_SYMBOL(ttm_bo_kmap); · 22 unmodified lines
597void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)603void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
598{604{
599 struct ttm_buffer_object *bo = map->bo;605 struct ttm_buffer_object *bo = map->bo;
600 struct ttm_mem_type_manager *man =606 struct ttm_resource_manager *man =
601 &bo->bdev->man[bo->mem.mem_type];607 ttm_manager_type(bo->bdev, bo->mem.mem_type);
602 608
603 if (!map->virtual)609 if (!map->virtual)
604 return;610 return;
@@ -628,11 +634,11 @@ EXPORT_SYMBOL(ttm_bo_kunmap); · 23 unmodified lines
628int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,634int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
629 struct dma_fence *fence,635 struct dma_fence *fence,
630 bool evict,636 bool evict,
631 struct ttm_mem_reg *new_mem)637 struct ttm_resource *new_mem)
632{638{
633 struct ttm_bo_device *bdev = bo->bdev;639 struct ttm_bo_device *bdev = bo->bdev;
634 struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];640 struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
635 struct ttm_mem_reg *old_mem = &bo->mem;641 struct ttm_resource *old_mem = &bo->mem;
636 int ret;642 int ret;
637 struct ttm_buffer_object *ghost_obj;643 struct ttm_buffer_object *ghost_obj;
638 644
@@ -642,7 +648,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, · 3 unmodified lines
642 if (ret)648 if (ret)
643 return ret;649 return ret;
644 650
645 if (man->flags & TTM_MEMTYPE_FLAG_FIXED) {651 if (!man->use_tt) {
646 ttm_tt_destroy(bo->ttm);652 ttm_tt_destroy(bo->ttm);
647 bo->ttm = NULL;653 bo->ttm = NULL;
648 }654 }
@@ -671,7 +677,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, · 22 unmodified lines
671 * bo to be unbound and destroyed.677 * bo to be unbound and destroyed.
672 */678 */
673 679
674 if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))680 if (man->use_tt)
675 ghost_obj->ttm = NULL;681 ghost_obj->ttm = NULL;
676 else682 else
677 bo->ttm = NULL;683 bo->ttm = NULL;
@@ -689,13 +695,13 @@ EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); · 11 unmodified lines
689 695
690int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,696int ttm_bo_pipeline_move(struct ttm_buffer_object *bo,
691 struct dma_fence *fence, bool evict,697 struct dma_fence *fence, bool evict,
692 struct ttm_mem_reg *new_mem)698 struct ttm_resource *new_mem)
693{699{
694 struct ttm_bo_device *bdev = bo->bdev;700 struct ttm_bo_device *bdev = bo->bdev;
695 struct ttm_mem_reg *old_mem = &bo->mem;701 struct ttm_resource *old_mem = &bo->mem;
696 702
697 struct ttm_mem_type_manager *from = &bdev->man[old_mem->mem_type];703 struct ttm_resource_manager *from = ttm_manager_type(bdev, old_mem->mem_type);
698 struct ttm_mem_type_manager *to = &bdev->man[new_mem->mem_type];704 struct ttm_resource_manager *to = ttm_manager_type(bdev, new_mem->mem_type);
699 705
700 int ret;706 int ret;
701 707
@@ -727,7 +733,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, · 25 unmodified lines
727 * bo to be unbound and destroyed.733 * bo to be unbound and destroyed.
728 */734 */
729 735
730 if (!(to->flags & TTM_MEMTYPE_FLAG_FIXED))736 if (to->use_tt)
731 ghost_obj->ttm = NULL;737 ghost_obj->ttm = NULL;
732 else738 else
733 bo->ttm = NULL;739 bo->ttm = NULL;
@@ -735,7 +741,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, · 1 unmodified line
735 dma_resv_unlock(&ghost_obj->base._resv);741 dma_resv_unlock(&ghost_obj->base._resv);
736 ttm_bo_put(ghost_obj);742 ttm_bo_put(ghost_obj);
737 743
738 } else if (from->flags & TTM_MEMTYPE_FLAG_FIXED) {744 } else if (!from->use_tt) {
739 745
740 /**746 /**
741 * BO doesn't have a TTM we need to bind/unbind. Just remember747 * BO doesn't have a TTM we need to bind/unbind. Just remember
@@ -765,7 +771,7 @@ int ttm_bo_pipeline_move(struct ttm_buffer_object *bo, · 23 unmodified lines
765 if (ret)771 if (ret)
766 return ret;772 return ret;
767 773
768 if (to->flags & TTM_MEMTYPE_FLAG_FIXED) {774 if (!to->use_tt) {
769 ttm_tt_destroy(bo->ttm);775 ttm_tt_destroy(bo->ttm);
770 bo->ttm = NULL;776 bo->ttm = NULL;
771 }777 }
drivers/gpu/drm/ttm/ttm_bo_vm.c+3−5
@@ -281,8 +281,8 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, · 280 unmodified lines
281 pgoff_t i;281 pgoff_t i;
282 vm_fault_t ret = VM_FAULT_NOPAGE;282 vm_fault_t ret = VM_FAULT_NOPAGE;
283 unsigned long address = vmf->address;283 unsigned long address = vmf->address;
284 struct ttm_mem_type_manager *man =284 struct ttm_resource_manager *man =
285 &bdev->man[bo->mem.mem_type];285 ttm_manager_type(bdev, bo->mem.mem_type);
286 286
287 /*287 /*
288 * Refuse to fault imported pages. This should be handled288 * Refuse to fault imported pages. This should be handled
@@ -308,9 +308,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, · 19 unmodified lines
308 }308 }
309 309
310 if (bo->moving != moving) {310 if (bo->moving != moving) {
311 spin_lock(&ttm_bo_glob.lru_lock);311 ttm_bo_move_to_lru_tail_unlocked(bo);
312 ttm_bo_move_to_lru_tail(bo, NULL);
313 spin_unlock(&ttm_bo_glob.lru_lock);
314 }312 }
315 dma_fence_put(moving);313 dma_fence_put(moving);
316 }314 }
drivers/gpu/drm/ttm/ttm_execbuf_util.c+2−10
@@ -93,7 +93,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, · 92 unmodified lines
93 list_for_each_entry(entry, list, head) {93 list_for_each_entry(entry, list, head) {
94 struct ttm_buffer_object *bo = entry->bo;94 struct ttm_buffer_object *bo = entry->bo;
95 95
96 ret = __ttm_bo_reserve(bo, intr, (ticket == NULL), ticket);96 ret = ttm_bo_reserve(bo, intr, (ticket == NULL), ticket);
97 if (ret == -EALREADY && dups) {97 if (ret == -EALREADY && dups) {
98 struct ttm_validate_buffer *safe = entry;98 struct ttm_validate_buffer *safe = entry;
99 entry = list_prev_entry(entry, head);99 entry = list_prev_entry(entry, head);
@@ -119,13 +119,7 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, · 19 unmodified lines
119 ttm_eu_backoff_reservation_reverse(list, entry);119 ttm_eu_backoff_reservation_reverse(list, entry);
120 120
121 if (ret == -EDEADLK) {121 if (ret == -EDEADLK) {
122 if (intr) {122 ret = ttm_bo_reserve_slowpath(bo, intr, ticket);
123 ret = dma_resv_lock_slow_interruptible(bo->base.resv,
124 ticket);
125 } else {
126 dma_resv_lock_slow(bo->base.resv, ticket);
127 ret = 0;
128 }
129 }123 }
130 124
131 if (!ret && entry->num_shared)125 if (!ret && entry->num_shared)
@@ -133,8 +127,6 @@ int ttm_eu_reserve_buffers(struct ww_acquire_ctx *ticket, · 1 unmodified line
133 entry->num_shared);127 entry->num_shared);
134 128
135 if (unlikely(ret != 0)) {129 if (unlikely(ret != 0)) {
136 if (ret == -EINTR)
137 ret = -ERESTARTSYS;
138 if (ticket) {130 if (ticket) {
139 ww_acquire_done(ticket);131 ww_acquire_done(ticket);
140 ww_acquire_fini(ticket);132 ww_acquire_fini(ticket);
drivers/gpu/drm/ttm/ttm_range_manager.crenamed from drivers/gpu/drm/ttm/ttm_bo_manager.c+60−29
@@ -44,16 +44,22 @@ · 43 unmodified lines
44 */44 */
45 45
46struct ttm_range_manager {46struct ttm_range_manager {
47 struct ttm_resource_manager manager;
47 struct drm_mm mm;48 struct drm_mm mm;
48 spinlock_t lock;49 spinlock_t lock;
49};50};
50 51
51static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man,52static inline struct ttm_range_manager *to_range_manager(struct ttm_resource_manager *man)
53{
54 return container_of(man, struct ttm_range_manager, manager);
55}
56
57static int ttm_range_man_alloc(struct ttm_resource_manager *man,
52 struct ttm_buffer_object *bo,58 struct ttm_buffer_object *bo,
53 const struct ttm_place *place,59 const struct ttm_place *place,
54 struct ttm_mem_reg *mem)60 struct ttm_resource *mem)
55{61{
56 struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;62 struct ttm_range_manager *rman = to_range_manager(man);
57 struct drm_mm *mm = &rman->mm;63 struct drm_mm *mm = &rman->mm;
58 struct drm_mm_node *node;64 struct drm_mm_node *node;
59 enum drm_mm_insert_mode mode;65 enum drm_mm_insert_mode mode;
@@ -89,10 +95,10 @@ static int ttm_bo_man_get_node(struct ttm_mem_type_manager *man, · 29 unmodified lines
89 return ret;95 return ret;
90}96}
91 97
92static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man,98static void ttm_range_man_free(struct ttm_resource_manager *man,
93 struct ttm_mem_reg *mem)99 struct ttm_resource *mem)
94{100{
95 struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;101 struct ttm_range_manager *rman = to_range_manager(man);
96 102
97 if (mem->mm_node) {103 if (mem->mm_node) {
98 spin_lock(&rman->lock);104 spin_lock(&rman->lock);
@@ -104,53 +110,78 @@ static void ttm_bo_man_put_node(struct ttm_mem_type_manager *man, · 5 unmodified lines
104 }110 }
105}111}
106 112
107static int ttm_bo_man_init(struct ttm_mem_type_manager *man,113static const struct ttm_resource_manager_func ttm_range_manager_func;
108 unsigned long p_size)114
115int ttm_range_man_init(struct ttm_bo_device *bdev,
116 unsigned type,
117 uint32_t available_caching,
118 uint32_t default_caching,
119 bool use_tt,
120 unsigned long p_size)
109{121{
122 struct ttm_resource_manager *man;
110 struct ttm_range_manager *rman;123 struct ttm_range_manager *rman;
111 124
112 rman = kzalloc(sizeof(*rman), GFP_KERNEL);125 rman = kzalloc(sizeof(*rman), GFP_KERNEL);
113 if (!rman)126 if (!rman)
114 return -ENOMEM;127 return -ENOMEM;
115 128
129 man = &rman->manager;
130 man->available_caching = available_caching;
131 man->default_caching = default_caching;
132 man->use_tt = use_tt;
133
134 man->func = &ttm_range_manager_func;
135
136 ttm_resource_manager_init(man, p_size);
137
116 drm_mm_init(&rman->mm, 0, p_size);138 drm_mm_init(&rman->mm, 0, p_size);
117 spin_lock_init(&rman->lock);139 spin_lock_init(&rman->lock);
118 man->priv = rman;140
141 ttm_set_driver_manager(bdev, type, &rman->manager);
142 ttm_resource_manager_set_used(man, true);
119 return 0;143 return 0;
120}144}
145EXPORT_SYMBOL(ttm_range_man_init);
121 146
122static int ttm_bo_man_takedown(struct ttm_mem_type_manager *man)147int ttm_range_man_fini(struct ttm_bo_device *bdev,
148 unsigned type)
123{149{
124 struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;150 struct ttm_resource_manager *man = ttm_manager_type(bdev, type);
151 struct ttm_range_manager *rman = to_range_manager(man);
125 struct drm_mm *mm = &rman->mm;152 struct drm_mm *mm = &rman->mm;
153 int ret;
154
155 ttm_resource_manager_set_used(man, false);
156
157 ret = ttm_resource_manager_force_list_clean(bdev, man);
158 if (ret)
159 return ret;
126 160
127 spin_lock(&rman->lock);161 spin_lock(&rman->lock);
128 if (drm_mm_clean(mm)) {162 drm_mm_clean(mm);
129 drm_mm_takedown(mm);163 drm_mm_takedown(mm);
130 spin_unlock(&rman->lock);
131 kfree(rman);
132 man->priv = NULL;
133 return 0;
134 }
135 spin_unlock(&rman->lock);164 spin_unlock(&rman->lock);
136 return -EBUSY;165
166 ttm_resource_manager_cleanup(man);
167 ttm_set_driver_manager(bdev, type, NULL);
168 kfree(rman);
169 return 0;
137}170}
171EXPORT_SYMBOL(ttm_range_man_fini);
138 172
139static void ttm_bo_man_debug(struct ttm_mem_type_manager *man,173static void ttm_range_man_debug(struct ttm_resource_manager *man,
140 struct drm_printer *printer)174 struct drm_printer *printer)
141{175{
142 struct ttm_range_manager *rman = (struct ttm_range_manager *) man->priv;176 struct ttm_range_manager *rman = to_range_manager(man);
143 177
144 spin_lock(&rman->lock);178 spin_lock(&rman->lock);
145 drm_mm_print(&rman->mm, printer);179 drm_mm_print(&rman->mm, printer);
146 spin_unlock(&rman->lock);180 spin_unlock(&rman->lock);
147}181}
148 182
149const struct ttm_mem_type_manager_func ttm_bo_manager_func = {183static const struct ttm_resource_manager_func ttm_range_manager_func = {
150 .init = ttm_bo_man_init,184 .alloc = ttm_range_man_alloc,
151 .takedown = ttm_bo_man_takedown,185 .free = ttm_range_man_free,
152 .get_node = ttm_bo_man_get_node,186 .debug = ttm_range_man_debug
153 .put_node = ttm_bo_man_put_node,
154 .debug = ttm_bo_man_debug
155};187};
156EXPORT_SYMBOL(ttm_bo_manager_func);
drivers/gpu/drm/ttm/ttm_resource.c+151−0
@@ -0,0 +1,151 @@
1/*
2 * Copyright 2020 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Christian König
23 */
24
25#include <drm/ttm/ttm_resource.h>
26#include <drm/ttm/ttm_bo_driver.h>
27
28int ttm_resource_alloc(struct ttm_buffer_object *bo,
29 const struct ttm_place *place,
30 struct ttm_resource *res)
31{
32 struct ttm_resource_manager *man =
33 ttm_manager_type(bo->bdev, res->mem_type);
34
35 res->mm_node = NULL;
36 if (!man->func || !man->func->alloc)
37 return 0;
38
39 return man->func->alloc(man, bo, place, res);
40}
41
42void ttm_resource_free(struct ttm_buffer_object *bo, struct ttm_resource *res)
43{
44 struct ttm_resource_manager *man =
45 ttm_manager_type(bo->bdev, res->mem_type);
46
47 if (man->func && man->func->free)
48 man->func->free(man, res);
49
50 res->mm_node = NULL;
51 res->mem_type = TTM_PL_SYSTEM;
52}
53EXPORT_SYMBOL(ttm_resource_free);
54
55/**
56 * ttm_resource_manager_init
57 *
58 * @man: memory manager object to init
59 * @p_size: size managed area in pages.
60 *
61 * Initialise core parts of a manager object.
62 */
63void ttm_resource_manager_init(struct ttm_resource_manager *man,
64 unsigned long p_size)
65{
66 unsigned i;
67
68 man->use_io_reserve_lru = false;
69 mutex_init(&man->io_reserve_mutex);
70 spin_lock_init(&man->move_lock);
71 INIT_LIST_HEAD(&man->io_reserve_lru);
72 man->size = p_size;
73
74 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i)
75 INIT_LIST_HEAD(&man->lru[i]);
76 man->move = NULL;
77}
78EXPORT_SYMBOL(ttm_resource_manager_init);
79
80/*
81 * ttm_resource_manager_force_list_clean
82 *
83 * @bdev - device to use
84 * @man - manager to use
85 *
86 * Force all the objects out of a memory manager until clean.
87 * Part of memory manager cleanup sequence.
88 */
89int ttm_resource_manager_force_list_clean(struct ttm_bo_device *bdev,
90 struct ttm_resource_manager *man)
91{
92 struct ttm_operation_ctx ctx = {
93 .interruptible = false,
94 .no_wait_gpu = false,
95 .flags = TTM_OPT_FLAG_FORCE_ALLOC
96 };
97 struct ttm_bo_global *glob = &ttm_bo_glob;
98 struct dma_fence *fence;
99 int ret;
100 unsigned i;
101
102 /*
103 * Can't use standard list traversal since we're unlocking.
104 */
105
106 spin_lock(&glob->lru_lock);
107 for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) {
108 while (!list_empty(&man->lru[i])) {
109 spin_unlock(&glob->lru_lock);
110 ret = ttm_mem_evict_first(bdev, man, NULL, &ctx,
111 NULL);
112 if (ret)
113 return ret;
114 spin_lock(&glob->lru_lock);
115 }
116 }
117 spin_unlock(&glob->lru_lock);
118
119 spin_lock(&man->move_lock);
120 fence = dma_fence_get(man->move);
121 spin_unlock(&man->move_lock);
122
123 if (fence) {
124 ret = dma_fence_wait(fence, false);
125 dma_fence_put(fence);
126 if (ret)
127 return ret;
128 }
129
130 return 0;
131}
132EXPORT_SYMBOL(ttm_resource_manager_force_list_clean);
133
134/**
135 * ttm_resource_manager_debug
136 *
137 * @man: manager type to dump.
138 * @p: printer to use for debug.
139 */
140void ttm_resource_manager_debug(struct ttm_resource_manager *man,
141 struct drm_printer *p)
142{
143 drm_printf(p, " use_type: %d\n", man->use_type);
144 drm_printf(p, " use_tt: %d\n", man->use_tt);
145 drm_printf(p, " size: %llu\n", man->size);
146 drm_printf(p, " available_caching: 0x%08X\n", man->available_caching);
147 drm_printf(p, " default_caching: 0x%08X\n", man->default_caching);
148 if (man->func && man->func->debug)
149 (*man->func->debug)(man, p);
150}
151EXPORT_SYMBOL(ttm_resource_manager_debug);
drivers/gpu/drm/ttm/ttm_tt.c+4−2
@@ -50,6 +50,9 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) · 49 unmodified lines
50 50
51 dma_resv_assert_held(bo->base.resv);51 dma_resv_assert_held(bo->base.resv);
52 52
53 if (bo->ttm)
54 return 0;
55
53 if (bdev->need_dma32)56 if (bdev->need_dma32)
54 page_flags |= TTM_PAGE_FLAG_DMA32;57 page_flags |= TTM_PAGE_FLAG_DMA32;
55 58
@@ -67,7 +70,6 @@ int ttm_tt_create(struct ttm_buffer_object *bo, bool zero_alloc) · 11 unmodified lines
67 page_flags |= TTM_PAGE_FLAG_SG;70 page_flags |= TTM_PAGE_FLAG_SG;
68 break;71 break;
69 default:72 default:
70 bo->ttm = NULL;
71 pr_err("Illegal buffer object type\n");73 pr_err("Illegal buffer object type\n");
72 return -EINVAL;74 return -EINVAL;
73 }75 }
@@ -314,7 +316,7 @@ void ttm_tt_unbind(struct ttm_tt *ttm) · 240 unmodified lines
314 }316 }
315}317}
316 318
317int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_mem_reg *bo_mem,319int ttm_tt_bind(struct ttm_tt *ttm, struct ttm_resource *bo_mem,
318 struct ttm_operation_ctx *ctx)320 struct ttm_operation_ctx *ctx)
319{321{
320 int ret = 0;322 int ret = 0;
drivers/gpu/drm/v3d/v3d_drv.c+1−12
@@ -358,18 +358,7 @@ static struct platform_driver v3d_platform_driver = { · 357 unmodified lines
358 },358 },
359};359};
360 360
361static int __init v3d_drm_register(void)361module_platform_driver(v3d_platform_driver);
362{
363 return platform_driver_register(&v3d_platform_driver);
364}
365
366static void __exit v3d_drm_unregister(void)
367{
368 platform_driver_unregister(&v3d_platform_driver);
369}
370
371module_init(v3d_drm_register);
372module_exit(v3d_drm_unregister);
373 362
374MODULE_ALIAS("platform:v3d-drm");363MODULE_ALIAS("platform:v3d-drm");
375MODULE_DESCRIPTION("Broadcom V3D DRM Driver");364MODULE_DESCRIPTION("Broadcom V3D DRM Driver");
drivers/gpu/drm/vgem/vgem_drv.c+1−1
@@ -471,8 +471,8 @@ static int __init vgem_init(void) · 470 unmodified lines
471 471
472out_put:472out_put:
473 drm_dev_put(&vgem_device->drm);473 drm_dev_put(&vgem_device->drm);
474 platform_device_unregister(vgem_device->platform);
474 return ret;475 return ret;
475
476out_unregister:476out_unregister:
477 platform_device_unregister(vgem_device->platform);477 platform_device_unregister(vgem_device->platform);
478out_free:478out_free:
drivers/gpu/drm/virtio/Kconfig+1−0
@@ -4,6 +4,7 @@ config DRM_VIRTIO_GPU · 3 unmodified lines
4 depends on DRM && VIRTIO && MMU4 depends on DRM && VIRTIO && MMU
5 select DRM_KMS_HELPER5 select DRM_KMS_HELPER
6 select DRM_GEM_SHMEM_HELPER6 select DRM_GEM_SHMEM_HELPER
7 select VIRTIO_DMA_SHARED_BUFFER
7 help8 help
8 This is the virtual GPU driver for virtio. It can be used with9 This is the virtual GPU driver for virtio. It can be used with
9 QEMU based VMMs (like KVM or Xen).10 QEMU based VMMs (like KVM or Xen).
drivers/gpu/drm/virtio/virtgpu_display.c+0−2
@@ -165,8 +165,6 @@ static int virtio_gpu_conn_get_modes(struct drm_connector *connector) · 164 unmodified lines
165 count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);165 count = drm_add_modes_noedid(connector, XRES_MAX, YRES_MAX);
166 166
167 if (width == 0 || height == 0) {167 if (width == 0 || height == 0) {
168 width = XRES_DEF;
169 height = YRES_DEF;
170 drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);168 drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF);
171 } else {169 } else {
172 DRM_DEBUG("add mode: %dx%d\n", width, height);170 DRM_DEBUG("add mode: %dx%d\n", width, height);
drivers/gpu/drm/virtio/virtgpu_drv.c+3−0
@@ -165,6 +165,7 @@ static unsigned int features[] = { · 164 unmodified lines
165 VIRTIO_GPU_F_VIRGL,165 VIRTIO_GPU_F_VIRGL,
166#endif166#endif
167 VIRTIO_GPU_F_EDID,167 VIRTIO_GPU_F_EDID,
168 VIRTIO_GPU_F_RESOURCE_UUID,
168};169};
169static struct virtio_driver virtio_gpu_driver = {170static struct virtio_driver virtio_gpu_driver = {
170 .feature_table = features,171 .feature_table = features,
@@ -202,6 +203,8 @@ static struct drm_driver driver = { · 31 unmodified lines
202 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,203 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
203 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,204 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
204 .gem_prime_mmap = drm_gem_prime_mmap,205 .gem_prime_mmap = drm_gem_prime_mmap,
206 .gem_prime_export = virtgpu_gem_prime_export,
207 .gem_prime_import = virtgpu_gem_prime_import,
205 .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table,208 .gem_prime_import_sg_table = virtgpu_gem_prime_import_sg_table,
206 209
207 .gem_create_object = virtio_gpu_create_object,210 .gem_create_object = virtio_gpu_create_object,
drivers/gpu/drm/virtio/virtgpu_drv.h+21−0
@@ -49,6 +49,10 @@ · 48 unmodified lines
49#define DRIVER_MINOR 149#define DRIVER_MINOR 1
50#define DRIVER_PATCHLEVEL 050#define DRIVER_PATCHLEVEL 0
51 51
52#define UUID_INITIALIZING 0
53#define UUID_INITIALIZED 1
54#define UUID_INITIALIZATION_FAILED 2
55
52struct virtio_gpu_object_params {56struct virtio_gpu_object_params {
53 uint32_t format;57 uint32_t format;
54 uint32_t width;58 uint32_t width;
@@ -71,6 +75,9 @@ struct virtio_gpu_object { · 16 unmodified lines
71 uint32_t hw_res_handle;75 uint32_t hw_res_handle;
72 bool dumb;76 bool dumb;
73 bool created;77 bool created;
78
79 int uuid_state;
80 uuid_t uuid;
74};81};
75#define gem_to_virtio_gpu_obj(gobj) \82#define gem_to_virtio_gpu_obj(gobj) \
76 container_of((gobj), struct virtio_gpu_object, base.base)83 container_of((gobj), struct virtio_gpu_object, base.base)
@@ -200,6 +207,7 @@ struct virtio_gpu_device { · 123 unmodified lines
200 bool has_virgl_3d;207 bool has_virgl_3d;
201 bool has_edid;208 bool has_edid;
202 bool has_indirect;209 bool has_indirect;
210 bool has_resource_assign_uuid;
203 211
204 struct work_struct config_changed_work;212 struct work_struct config_changed_work;
205 213
@@ -210,6 +218,9 @@ struct virtio_gpu_device { · 4 unmodified lines
210 struct virtio_gpu_drv_capset *capsets;218 struct virtio_gpu_drv_capset *capsets;
211 uint32_t num_capsets;219 uint32_t num_capsets;
212 struct list_head cap_cache;220 struct list_head cap_cache;
221
222 /* protects resource state when exporting */
223 spinlock_t resource_export_lock;
213};224};
214 225
215struct virtio_gpu_fpriv {226struct virtio_gpu_fpriv {
@@ -336,6 +347,10 @@ void virtio_gpu_dequeue_fence_func(struct work_struct *work); · 120 unmodified lines
336 347
337void virtio_gpu_notify(struct virtio_gpu_device *vgdev);348void virtio_gpu_notify(struct virtio_gpu_device *vgdev);
338 349
350int
351virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev,
352 struct virtio_gpu_object_array *objs);
353
339/* virtgpu_display.c */354/* virtgpu_display.c */
340void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);355void virtio_gpu_modeset_init(struct virtio_gpu_device *vgdev);
341void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);356void virtio_gpu_modeset_fini(struct virtio_gpu_device *vgdev);
@@ -367,6 +382,12 @@ int virtio_gpu_object_create(struct virtio_gpu_device *vgdev, · 25 unmodified lines
367bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo);382bool virtio_gpu_is_shmem(struct virtio_gpu_object *bo);
368 383
369/* virtgpu_prime.c */384/* virtgpu_prime.c */
385struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
386 int flags);
387struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
388 struct dma_buf *buf);
389int virtgpu_gem_prime_get_uuid(struct drm_gem_object *obj,
390 uuid_t *uuid);
370struct drm_gem_object *virtgpu_gem_prime_import_sg_table(391struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
371 struct drm_device *dev, struct dma_buf_attachment *attach,392 struct drm_device *dev, struct dma_buf_attachment *attach,
372 struct sg_table *sgt);393 struct sg_table *sgt);
drivers/gpu/drm/virtio/virtgpu_gem.c+1−2
@@ -154,9 +154,8 @@ void virtio_gpu_gem_object_close(struct drm_gem_object *obj, · 153 unmodified lines
154struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents)154struct virtio_gpu_object_array *virtio_gpu_array_alloc(u32 nents)
155{155{
156 struct virtio_gpu_object_array *objs;156 struct virtio_gpu_object_array *objs;
157 size_t size = sizeof(*objs) + sizeof(objs->objs[0]) * nents;
158 157
159 objs = kmalloc(size, GFP_KERNEL);158 objs = kmalloc(struct_size(objs, objs, nents), GFP_KERNEL);
160 if (!objs)159 if (!objs)
161 return NULL;160 return NULL;
162 161
drivers/gpu/drm/virtio/virtgpu_kms.c+4−0
@@ -118,6 +118,7 @@ int virtio_gpu_init(struct drm_device *dev) · 117 unmodified lines
118 vgdev->dev = dev->dev;118 vgdev->dev = dev->dev;
119 119
120 spin_lock_init(&vgdev->display_info_lock);120 spin_lock_init(&vgdev->display_info_lock);
121 spin_lock_init(&vgdev->resource_export_lock);
121 ida_init(&vgdev->ctx_id_ida);122 ida_init(&vgdev->ctx_id_ida);
122 ida_init(&vgdev->resource_ida);123 ida_init(&vgdev->resource_ida);
123 init_waitqueue_head(&vgdev->resp_wq);124 init_waitqueue_head(&vgdev->resp_wq);
@@ -146,6 +147,9 @@ int virtio_gpu_init(struct drm_device *dev) · 22 unmodified lines
146 if (virtio_has_feature(vgdev->vdev, VIRTIO_RING_F_INDIRECT_DESC)) {147 if (virtio_has_feature(vgdev->vdev, VIRTIO_RING_F_INDIRECT_DESC)) {
147 vgdev->has_indirect = true;148 vgdev->has_indirect = true;
148 }149 }
150 if (virtio_has_feature(vgdev->vdev, VIRTIO_GPU_F_RESOURCE_UUID)) {
151 vgdev->has_resource_assign_uuid = true;
152 }
149 153
150 DRM_INFO("features: %cvirgl %cedid\n",154 DRM_INFO("features: %cvirgl %cedid\n",
151 vgdev->has_virgl_3d ? '+' : '-',155 vgdev->has_virgl_3d ? '+' : '-',
drivers/gpu/drm/virtio/virtgpu_object.c+7−1
@@ -151,7 +151,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev, · 150 unmodified lines
151 if (ret < 0)151 if (ret < 0)
152 return -EINVAL;152 return -EINVAL;
153 153
154 shmem->pages = drm_gem_shmem_get_pages_sgt(&bo->base.base);154 /*
155 * virtio_gpu uses drm_gem_shmem_get_sg_table instead of
156 * drm_gem_shmem_get_pages_sgt because virtio has it's own set of
157 * dma-ops. This is discouraged for other drivers, but should be fine
158 * since virtio_gpu doesn't support dma-buf import from other devices.
159 */
160 shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base);
155 if (!shmem->pages) {161 if (!shmem->pages) {
156 drm_gem_shmem_unpin(&bo->base.base);162 drm_gem_shmem_unpin(&bo->base.base);
157 return -EINVAL;163 return -EINVAL;
drivers/gpu/drm/virtio/virtgpu_prime.c+93−3
@@ -23,12 +23,102 @@ · 22 unmodified lines
23 */23 */
24 24
25#include <drm/drm_prime.h>25#include <drm/drm_prime.h>
26#include <linux/virtio_dma_buf.h>
26 27
27#include "virtgpu_drv.h"28#include "virtgpu_drv.h"
28 29
29/* Empty Implementations as there should not be any other driver for a virtual30static int virtgpu_virtio_get_uuid(struct dma_buf *buf,
30 * device that might share buffers with virtgpu31 uuid_t *uuid)
31 */32{
33 struct drm_gem_object *obj = buf->priv;
34 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
35 struct virtio_gpu_device *vgdev = obj->dev->dev_private;
36
37 wait_event(vgdev->resp_wq, bo->uuid_state != UUID_INITIALIZING);
38 if (bo->uuid_state != UUID_INITIALIZED)
39 return -ENODEV;
40
41 uuid_copy(uuid, &bo->uuid);
42
43 return 0;
44}
45
46const struct virtio_dma_buf_ops virtgpu_dmabuf_ops = {
47 .ops = {
48 .cache_sgt_mapping = true,
49 .attach = virtio_dma_buf_attach,
50 .detach = drm_gem_map_detach,
51 .map_dma_buf = drm_gem_map_dma_buf,
52 .unmap_dma_buf = drm_gem_unmap_dma_buf,
53 .release = drm_gem_dmabuf_release,
54 .mmap = drm_gem_dmabuf_mmap,
55 .vmap = drm_gem_dmabuf_vmap,
56 .vunmap = drm_gem_dmabuf_vunmap,
57 },
58 .device_attach = drm_gem_map_attach,
59 .get_uuid = virtgpu_virtio_get_uuid,
60};
61
62struct dma_buf *virtgpu_gem_prime_export(struct drm_gem_object *obj,
63 int flags)
64{
65 struct dma_buf *buf;
66 struct drm_device *dev = obj->dev;
67 struct virtio_gpu_device *vgdev = dev->dev_private;
68 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(obj);
69 struct virtio_gpu_object_array *objs;
70 int ret = 0;
71 DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
72
73 if (vgdev->has_resource_assign_uuid) {
74 objs = virtio_gpu_array_alloc(1);
75 if (!objs)
76 return ERR_PTR(-ENOMEM);
77 virtio_gpu_array_add_obj(objs, &bo->base.base);
78
79 ret = virtio_gpu_cmd_resource_assign_uuid(vgdev, objs);
80 if (ret)
81 return ERR_PTR(ret);
82 virtio_gpu_notify(vgdev);
83 } else {
84 bo->uuid_state = UUID_INITIALIZATION_FAILED;
85 }
86
87 exp_info.ops = &virtgpu_dmabuf_ops.ops;
88 exp_info.size = obj->size;
89 exp_info.flags = flags;
90 exp_info.priv = obj;
91 exp_info.resv = obj->resv;
92
93 buf = virtio_dma_buf_export(&exp_info);
94 if (IS_ERR(buf))
95 return buf;
96
97 drm_dev_get(dev);
98 drm_gem_object_get(obj);
99
100 return buf;
101}
102
103struct drm_gem_object *virtgpu_gem_prime_import(struct drm_device *dev,
104 struct dma_buf *buf)
105{
106 struct drm_gem_object *obj;
107
108 if (buf->ops == &virtgpu_dmabuf_ops.ops) {
109 obj = buf->priv;
110 if (obj->dev == dev) {
111 /*
112 * Importing dmabuf exported from our own gem increases
113 * refcount on gem itself instead of f_count of dmabuf.
114 */
115 drm_gem_object_get(obj);
116 return obj;
117 }
118 }
119
120 return drm_gem_prime_import(dev, buf);
121}
32 122
33struct drm_gem_object *virtgpu_gem_prime_import_sg_table(123struct drm_gem_object *virtgpu_gem_prime_import_sg_table(
34 struct drm_device *dev, struct dma_buf_attachment *attach,124 struct drm_device *dev, struct dma_buf_attachment *attach,
drivers/gpu/drm/virtio/virtgpu_vq.c+55−0
@@ -1107,3 +1107,58 @@ void virtio_gpu_cursor_ping(struct virtio_gpu_device *vgdev, · 1106 unmodified lines
1107 memcpy(cur_p, &output->cursor, sizeof(output->cursor));1107 memcpy(cur_p, &output->cursor, sizeof(output->cursor));
1108 virtio_gpu_queue_cursor(vgdev, vbuf);1108 virtio_gpu_queue_cursor(vgdev, vbuf);
1109}1109}
1110
1111static void virtio_gpu_cmd_resource_uuid_cb(struct virtio_gpu_device *vgdev,
1112 struct virtio_gpu_vbuffer *vbuf)
1113{
1114 struct virtio_gpu_object *obj =
1115 gem_to_virtio_gpu_obj(vbuf->objs->objs[0]);
1116 struct virtio_gpu_resp_resource_uuid *resp =
1117 (struct virtio_gpu_resp_resource_uuid *)vbuf->resp_buf;
1118 uint32_t resp_type = le32_to_cpu(resp->hdr.type);
1119
1120 spin_lock(&vgdev->resource_export_lock);
1121 WARN_ON(obj->uuid_state != UUID_INITIALIZING);
1122
1123 if (resp_type == VIRTIO_GPU_RESP_OK_RESOURCE_UUID &&
1124 obj->uuid_state == UUID_INITIALIZING) {
1125 memcpy(&obj->uuid.b, resp->uuid, sizeof(obj->uuid.b));
1126 obj->uuid_state = UUID_INITIALIZED;
1127 } else {
1128 obj->uuid_state = UUID_INITIALIZATION_FAILED;
1129 }
1130 spin_unlock(&vgdev->resource_export_lock);
1131
1132 wake_up_all(&vgdev->resp_wq);
1133}
1134
1135int
1136virtio_gpu_cmd_resource_assign_uuid(struct virtio_gpu_device *vgdev,
1137 struct virtio_gpu_object_array *objs)
1138{
1139 struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
1140 struct virtio_gpu_resource_assign_uuid *cmd_p;
1141 struct virtio_gpu_vbuffer *vbuf;
1142 struct virtio_gpu_resp_resource_uuid *resp_buf;
1143
1144 resp_buf = kzalloc(sizeof(*resp_buf), GFP_KERNEL);
1145 if (!resp_buf) {
1146 spin_lock(&vgdev->resource_export_lock);
1147 bo->uuid_state = UUID_INITIALIZATION_FAILED;
1148 spin_unlock(&vgdev->resource_export_lock);
1149 virtio_gpu_array_put_free(objs);
1150 return -ENOMEM;
1151 }
1152
1153 cmd_p = virtio_gpu_alloc_cmd_resp
1154 (vgdev, virtio_gpu_cmd_resource_uuid_cb, &vbuf, sizeof(*cmd_p),
1155 sizeof(struct virtio_gpu_resp_resource_uuid), resp_buf);
1156 memset(cmd_p, 0, sizeof(*cmd_p));
1157
1158 cmd_p->hdr.type = cpu_to_le32(VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID);
1159 cmd_p->resource_id = cpu_to_le32(bo->hw_res_handle);
1160
1161 vbuf->objs = objs;
1162 virtio_gpu_queue_ctrl_buffer(vgdev, vbuf);
1163 return 0;
1164}
drivers/gpu/drm/vkms/vkms_composer.c+18−4
@@ -33,7 +33,7 @@ static uint32_t compute_crc(void *vaddr_out, struct vkms_composer *composer) · 32 unmodified lines
33 + (i * composer->pitch)33 + (i * composer->pitch)
34 + (j * composer->cpp);34 + (j * composer->cpp);
35 /* XRGB format ignores Alpha channel */35 /* XRGB format ignores Alpha channel */
36 memset(vaddr_out + src_offset + 24, 0, 8);36 bitmap_clear(vaddr_out + src_offset, 24, 8);
37 crc = crc32_le(crc, vaddr_out + src_offset,37 crc = crc32_le(crc, vaddr_out + src_offset,
38 sizeof(u32));38 sizeof(u32));
39 }39 }
@@ -233,6 +233,22 @@ int vkms_verify_crc_source(struct drm_crtc *crtc, const char *src_name, · 193 unmodified lines
233 return 0;233 return 0;
234}234}
235 235
236static void vkms_set_composer(struct vkms_output *out, bool enabled)
237{
238 bool old_enabled;
239
240 if (enabled)
241 drm_crtc_vblank_get(&out->crtc);
242
243 spin_lock_irq(&out->lock);
244 old_enabled = out->composer_enabled;
245 out->composer_enabled = enabled;
246 spin_unlock_irq(&out->lock);
247
248 if (old_enabled)
249 drm_crtc_vblank_put(&out->crtc);
250}
251
236int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name)252int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name)
237{253{
238 struct vkms_output *out = drm_crtc_to_vkms_output(crtc);254 struct vkms_output *out = drm_crtc_to_vkms_output(crtc);
@@ -241,9 +257,7 @@ int vkms_set_crc_source(struct drm_crtc *crtc, const char *src_name) · 2 unmodified lines
241 257
242 ret = vkms_crc_parse_source(src_name, &enabled);258 ret = vkms_crc_parse_source(src_name, &enabled);
243 259
244 spin_lock_irq(&out->lock);260 vkms_set_composer(out, enabled);
245 out->composer_enabled = enabled;
246 spin_unlock_irq(&out->lock);
247 261
248 return ret;262 return ret;
249}263}
drivers/gpu/drm/vkms/vkms_drv.c+1−1
@@ -190,8 +190,8 @@ static int __init vkms_init(void) · 189 unmodified lines
190 190
191out_put:191out_put:
192 drm_dev_put(&vkms_device->drm);192 drm_dev_put(&vkms_device->drm);
193 platform_device_unregister(vkms_device->platform);
193 return ret;194 return ret;
194
195out_unregister:195out_unregister:
196 platform_device_unregister(vkms_device->platform);196 platform_device_unregister(vkms_device->platform);
197out_free:197out_free:
drivers/gpu/drm/vmwgfx/vmwgfx_bo.c+2−2
@@ -1135,14 +1135,14 @@ void vmw_bo_swap_notify(struct ttm_buffer_object *bo) · 1134 unmodified lines
1135 * vmw_bo_move_notify - TTM move_notify_callback1135 * vmw_bo_move_notify - TTM move_notify_callback
1136 *1136 *
1137 * @bo: The TTM buffer object about to move.1137 * @bo: The TTM buffer object about to move.
1138 * @mem: The struct ttm_mem_reg indicating to what memory1138 * @mem: The struct ttm_resource indicating to what memory
1139 * region the move is taking place.1139 * region the move is taking place.
1140 *1140 *
1141 * Detaches cached maps and device bindings that require that the1141 * Detaches cached maps and device bindings that require that the
1142 * buffer doesn't move.1142 * buffer doesn't move.
1143 */1143 */
1144void vmw_bo_move_notify(struct ttm_buffer_object *bo,1144void vmw_bo_move_notify(struct ttm_buffer_object *bo,
1145 struct ttm_mem_reg *mem)1145 struct ttm_resource *mem)
1146{1146{
1147 struct vmw_buffer_object *vbo;1147 struct vmw_buffer_object *vbo;
1148 1148
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c+54−19
@@ -620,6 +620,29 @@ static int vmw_dma_masks(struct vmw_private *dev_priv) · 619 unmodified lines
620 return ret;620 return ret;
621}621}
622 622
623static int vmw_vram_manager_init(struct vmw_private *dev_priv)
624{
625 int ret;
626#ifdef CONFIG_TRANSPARENT_HUGEPAGE
627 ret = vmw_thp_init(dev_priv);
628#else
629 ret = ttm_range_man_init(&dev_priv->bdev, TTM_PL_VRAM,
630 TTM_PL_FLAG_CACHED, TTM_PL_FLAG_CACHED,
631 false, dev_priv->vram_size >> PAGE_SHIFT);
632#endif
633 ttm_resource_manager_set_used(ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM), false);
634 return ret;
635}
636
637static void vmw_vram_manager_fini(struct vmw_private *dev_priv)
638{
639#ifdef CONFIG_TRANSPARENT_HUGEPAGE
640 vmw_thp_fini(dev_priv);
641#else
642 ttm_range_man_fini(&dev_priv->bdev, TTM_PL_VRAM);
643#endif
644}
645
623static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)646static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
624{647{
625 struct vmw_private *dev_priv;648 struct vmw_private *dev_priv;
@@ -859,23 +882,30 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 233 unmodified lines
859 DRM_ERROR("Failed initializing TTM buffer object driver.\n");882 DRM_ERROR("Failed initializing TTM buffer object driver.\n");
860 goto out_no_bdev;883 goto out_no_bdev;
861 }884 }
885 ttm_manager_type(&dev_priv->bdev, TTM_PL_SYSTEM)->available_caching =
886 TTM_PL_FLAG_CACHED;
862 887
863 /*888 /*
864 * Enable VRAM, but initially don't use it until SVGA is enabled and889 * Enable VRAM, but initially don't use it until SVGA is enabled and
865 * unhidden.890 * unhidden.
866 */891 */
867 ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM,892
868 (dev_priv->vram_size >> PAGE_SHIFT));893 ret = vmw_vram_manager_init(dev_priv);
869 if (unlikely(ret != 0)) {894 if (unlikely(ret != 0)) {
870 DRM_ERROR("Failed initializing memory manager for VRAM.\n");895 DRM_ERROR("Failed initializing memory manager for VRAM.\n");
871 goto out_no_vram;896 goto out_no_vram;
872 }897 }
873 dev_priv->bdev.man[TTM_PL_VRAM].use_type = false;
874 898
899 /*
900 * "Guest Memory Regions" is an aperture like feature with
901 * one slot per bo. There is an upper limit of the number of
902 * slots as well as the bo size.
903 */
875 dev_priv->has_gmr = true;904 dev_priv->has_gmr = true;
905 /* TODO: This is most likely not correct */
876 if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) ||906 if (((dev_priv->capabilities & (SVGA_CAP_GMR | SVGA_CAP_GMR2)) == 0) ||
877 refuse_dma || ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR,907 refuse_dma ||
878 VMW_PL_GMR) != 0) {908 vmw_gmrid_man_init(dev_priv, VMW_PL_GMR) != 0) {
879 DRM_INFO("No GMR memory available. "909 DRM_INFO("No GMR memory available. "
880 "Graphics memory resources are very limited.\n");910 "Graphics memory resources are very limited.\n");
881 dev_priv->has_gmr = false;911 dev_priv->has_gmr = false;
@@ -883,8 +913,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) · 1 unmodified line
883 913
884 if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS && !refuse_dma) {914 if (dev_priv->capabilities & SVGA_CAP_GBOBJECTS && !refuse_dma) {
885 dev_priv->has_mob = true;915 dev_priv->has_mob = true;
886 if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_MOB,916
887 VMW_PL_MOB) != 0) {917 if (vmw_gmrid_man_init(dev_priv, VMW_PL_MOB) != 0) {
888 DRM_INFO("No MOB memory available. "918 DRM_INFO("No MOB memory available. "
889 "3D will be disabled.\n");919 "3D will be disabled.\n");
890 dev_priv->has_mob = false;920 dev_priv->has_mob = false;
@@ -961,10 +991,10 @@ out_no_fifo: · 70 unmodified lines
961 vmw_kms_close(dev_priv);991 vmw_kms_close(dev_priv);
962out_no_kms:992out_no_kms:
963 if (dev_priv->has_mob)993 if (dev_priv->has_mob)
964 (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);994 vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB);
965 if (dev_priv->has_gmr)995 if (dev_priv->has_gmr)
966 (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);996 vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR);
967 (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);997 vmw_vram_manager_fini(dev_priv);
968out_no_vram:998out_no_vram:
969 (void)ttm_bo_device_release(&dev_priv->bdev);999 (void)ttm_bo_device_release(&dev_priv->bdev);
970out_no_bdev:1000out_no_bdev:
@@ -1012,12 +1042,12 @@ static void vmw_driver_unload(struct drm_device *dev) · 41 unmodified lines
1012 vmw_overlay_close(dev_priv);1042 vmw_overlay_close(dev_priv);
1013 1043
1014 if (dev_priv->has_gmr)1044 if (dev_priv->has_gmr)
1015 (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR);1045 vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR);
1016 (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM);
1017 1046
1018 vmw_release_device_early(dev_priv);1047 vmw_release_device_early(dev_priv);
1019 if (dev_priv->has_mob)1048 if (dev_priv->has_mob)
1020 (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_MOB);1049 vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB);
1050 vmw_vram_manager_fini(dev_priv);
1021 (void) ttm_bo_device_release(&dev_priv->bdev);1051 (void) ttm_bo_device_release(&dev_priv->bdev);
1022 drm_vma_offset_manager_destroy(&dev_priv->vma_manager);1052 drm_vma_offset_manager_destroy(&dev_priv->vma_manager);
1023 vmw_release_device_late(dev_priv);1053 vmw_release_device_late(dev_priv);
@@ -1159,10 +1189,12 @@ static void vmw_master_drop(struct drm_device *dev, · 135 unmodified lines
1159 */1189 */
1160static void __vmw_svga_enable(struct vmw_private *dev_priv)1190static void __vmw_svga_enable(struct vmw_private *dev_priv)
1161{1191{
1192 struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM);
1193
1162 spin_lock(&dev_priv->svga_lock);1194 spin_lock(&dev_priv->svga_lock);
1163 if (!dev_priv->bdev.man[TTM_PL_VRAM].use_type) {1195 if (!ttm_resource_manager_used(man)) {
1164 vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE);1196 vmw_write(dev_priv, SVGA_REG_ENABLE, SVGA_REG_ENABLE);
1165 dev_priv->bdev.man[TTM_PL_VRAM].use_type = true;1197 ttm_resource_manager_set_used(man, true);
1166 }1198 }
1167 spin_unlock(&dev_priv->svga_lock);1199 spin_unlock(&dev_priv->svga_lock);
1168}1200}
@@ -1188,9 +1220,11 @@ void vmw_svga_enable(struct vmw_private *dev_priv) · 19 unmodified lines
1188 */1220 */
1189static void __vmw_svga_disable(struct vmw_private *dev_priv)1221static void __vmw_svga_disable(struct vmw_private *dev_priv)
1190{1222{
1223 struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM);
1224
1191 spin_lock(&dev_priv->svga_lock);1225 spin_lock(&dev_priv->svga_lock);
1192 if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {1226 if (ttm_resource_manager_used(man)) {
1193 dev_priv->bdev.man[TTM_PL_VRAM].use_type = false;1227 ttm_resource_manager_set_used(man, false);
1194 vmw_write(dev_priv, SVGA_REG_ENABLE,1228 vmw_write(dev_priv, SVGA_REG_ENABLE,
1195 SVGA_REG_ENABLE_HIDE |1229 SVGA_REG_ENABLE_HIDE |
1196 SVGA_REG_ENABLE_ENABLE);1230 SVGA_REG_ENABLE_ENABLE);
@@ -1207,6 +1241,7 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv) · 10 unmodified lines
1207 */1241 */
1208void vmw_svga_disable(struct vmw_private *dev_priv)1242void vmw_svga_disable(struct vmw_private *dev_priv)
1209{1243{
1244 struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM);
1210 /*1245 /*
1211 * Disabling SVGA will turn off device modesetting capabilities, so1246 * Disabling SVGA will turn off device modesetting capabilities, so
1212 * notify KMS about that so that it doesn't cache atomic state that1247 * notify KMS about that so that it doesn't cache atomic state that
@@ -1222,8 +1257,8 @@ void vmw_svga_disable(struct vmw_private *dev_priv) · 9 unmodified lines
1222 vmw_kms_lost_device(dev_priv->dev);1257 vmw_kms_lost_device(dev_priv->dev);
1223 ttm_write_lock(&dev_priv->reservation_sem, false);1258 ttm_write_lock(&dev_priv->reservation_sem, false);
1224 spin_lock(&dev_priv->svga_lock);1259 spin_lock(&dev_priv->svga_lock);
1225 if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {1260 if (ttm_resource_manager_used(man)) {
1226 dev_priv->bdev.man[TTM_PL_VRAM].use_type = false;1261 ttm_resource_manager_set_used(man, false);
1227 spin_unlock(&dev_priv->svga_lock);1262 spin_unlock(&dev_priv->svga_lock);
1228 if (ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM))1263 if (ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM))
1229 DRM_ERROR("Failed evicting VRAM buffers.\n");1264 DRM_ERROR("Failed evicting VRAM buffers.\n");
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h+10−8
@@ -793,7 +793,7 @@ extern void vmw_resource_unreserve(struct vmw_resource *res, · 792 unmodified lines
793 struct vmw_buffer_object *new_backup,793 struct vmw_buffer_object *new_backup,
794 unsigned long new_backup_offset);794 unsigned long new_backup_offset);
795extern void vmw_query_move_notify(struct ttm_buffer_object *bo,795extern void vmw_query_move_notify(struct ttm_buffer_object *bo,
796 struct ttm_mem_reg *mem);796 struct ttm_resource *mem);
797extern int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob);797extern int vmw_query_readback_all(struct vmw_buffer_object *dx_query_mob);
798extern void vmw_resource_evict_all(struct vmw_private *dev_priv);798extern void vmw_resource_evict_all(struct vmw_private *dev_priv);
799extern void vmw_resource_unbind_list(struct vmw_buffer_object *vbo);799extern void vmw_resource_unbind_list(struct vmw_buffer_object *vbo);
@@ -878,7 +878,7 @@ extern void vmw_bo_fence_single(struct ttm_buffer_object *bo, · 78 unmodified lines
878extern void *vmw_bo_map_and_cache(struct vmw_buffer_object *vbo);878extern void *vmw_bo_map_and_cache(struct vmw_buffer_object *vbo);
879extern void vmw_bo_unmap(struct vmw_buffer_object *vbo);879extern void vmw_bo_unmap(struct vmw_buffer_object *vbo);
880extern void vmw_bo_move_notify(struct ttm_buffer_object *bo,880extern void vmw_bo_move_notify(struct ttm_buffer_object *bo,
881 struct ttm_mem_reg *mem);881 struct ttm_resource *mem);
882extern void vmw_bo_swap_notify(struct ttm_buffer_object *bo);882extern void vmw_bo_swap_notify(struct ttm_buffer_object *bo);
883extern struct vmw_buffer_object *883extern struct vmw_buffer_object *
884vmw_user_bo_noref_lookup(struct ttm_object_file *tfile, u32 handle);884vmw_user_bo_noref_lookup(struct ttm_object_file *tfile, u32 handle);
@@ -1019,10 +1019,12 @@ extern struct ttm_placement vmw_mob_placement; · 134 unmodified lines
1019extern struct ttm_placement vmw_mob_ne_placement;1019extern struct ttm_placement vmw_mob_ne_placement;
1020extern struct ttm_placement vmw_nonfixed_placement;1020extern struct ttm_placement vmw_nonfixed_placement;
1021extern struct ttm_bo_driver vmw_bo_driver;1021extern struct ttm_bo_driver vmw_bo_driver;
1022extern int vmw_bo_map_dma(struct ttm_buffer_object *bo);
1023extern void vmw_bo_unmap_dma(struct ttm_buffer_object *bo);
1024extern const struct vmw_sg_table *1022extern const struct vmw_sg_table *
1025vmw_bo_sg_table(struct ttm_buffer_object *bo);1023vmw_bo_sg_table(struct ttm_buffer_object *bo);
1024extern int vmw_bo_create_and_populate(struct vmw_private *dev_priv,
1025 unsigned long bo_size,
1026 struct ttm_buffer_object **bo_p);
1027
1026extern void vmw_piter_start(struct vmw_piter *viter,1028extern void vmw_piter_start(struct vmw_piter *viter,
1027 const struct vmw_sg_table *vsgt,1029 const struct vmw_sg_table *vsgt,
1028 unsigned long p_offs);1030 unsigned long p_offs);
@@ -1219,7 +1221,8 @@ int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv); · 190 unmodified lines
1219 * GMR Id manager1221 * GMR Id manager
1220 */1222 */
1221 1223
1222extern const struct ttm_mem_type_manager_func vmw_gmrid_manager_func;1224int vmw_gmrid_man_init(struct vmw_private *dev_priv, int type);
1225void vmw_gmrid_man_fini(struct vmw_private *dev_priv, int type);
1223 1226
1224/**1227/**
1225 * Prime - vmwgfx_prime.c1228 * Prime - vmwgfx_prime.c
@@ -1518,9 +1521,8 @@ vm_fault_t vmw_bo_vm_huge_fault(struct vm_fault *vmf, · 292 unmodified lines
1518 1521
1519/* Transparent hugepage support - vmwgfx_thp.c */1522/* Transparent hugepage support - vmwgfx_thp.c */
1520#ifdef CONFIG_TRANSPARENT_HUGEPAGE1523#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1521extern const struct ttm_mem_type_manager_func vmw_thp_func;1524extern int vmw_thp_init(struct vmw_private *dev_priv);
1522#else1525void vmw_thp_fini(struct vmw_private *dev_priv);
1523#define vmw_thp_func ttm_bo_manager_func
1524#endif1526#endif
1525 1527
1526/**1528/**
drivers/gpu/drm/vmwgfx/vmwgfx_gmrid_manager.c+42−33
@@ -37,6 +37,7 @@ · 36 unmodified lines
37#include <linux/kernel.h>37#include <linux/kernel.h>
38 38
39struct vmwgfx_gmrid_man {39struct vmwgfx_gmrid_man {
40 struct ttm_resource_manager manager;
40 spinlock_t lock;41 spinlock_t lock;
41 struct ida gmr_ida;42 struct ida gmr_ida;
42 uint32_t max_gmr_ids;43 uint32_t max_gmr_ids;
@@ -44,13 +45,17 @@ struct vmwgfx_gmrid_man { · 1 unmodified line
44 uint32_t used_gmr_pages;45 uint32_t used_gmr_pages;
45};46};
46 47
47static int vmw_gmrid_man_get_node(struct ttm_mem_type_manager *man,48static struct vmwgfx_gmrid_man *to_gmrid_manager(struct ttm_resource_manager *man)
49{
50 return container_of(man, struct vmwgfx_gmrid_man, manager);
51}
52
53static int vmw_gmrid_man_get_node(struct ttm_resource_manager *man,
48 struct ttm_buffer_object *bo,54 struct ttm_buffer_object *bo,
49 const struct ttm_place *place,55 const struct ttm_place *place,
50 struct ttm_mem_reg *mem)56 struct ttm_resource *mem)
51{57{
52 struct vmwgfx_gmrid_man *gman =58 struct vmwgfx_gmrid_man *gman = to_gmrid_manager(man);
53 (struct vmwgfx_gmrid_man *)man->priv;
54 int id;59 int id;
55 60
56 id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);61 id = ida_alloc_max(&gman->gmr_ida, gman->max_gmr_ids - 1, GFP_KERNEL);
@@ -79,11 +84,10 @@ nospace: · 22 unmodified lines
79 return -ENOSPC;84 return -ENOSPC;
80}85}
81 86
82static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man,87static void vmw_gmrid_man_put_node(struct ttm_resource_manager *man,
83 struct ttm_mem_reg *mem)88 struct ttm_resource *mem)
84{89{
85 struct vmwgfx_gmrid_man *gman =90 struct vmwgfx_gmrid_man *gman = to_gmrid_manager(man);
86 (struct vmwgfx_gmrid_man *)man->priv;
87 91
88 if (mem->mm_node) {92 if (mem->mm_node) {
89 ida_free(&gman->gmr_ida, mem->start);93 ida_free(&gman->gmr_ida, mem->start);
@@ -94,22 +98,30 @@ static void vmw_gmrid_man_put_node(struct ttm_mem_type_manager *man, · 4 unmodified lines
94 }98 }
95}99}
96 100
97static int vmw_gmrid_man_init(struct ttm_mem_type_manager *man,101static const struct ttm_resource_manager_func vmw_gmrid_manager_func;
98 unsigned long p_size)102
103int vmw_gmrid_man_init(struct vmw_private *dev_priv, int type)
99{104{
100 struct vmw_private *dev_priv =105 struct ttm_resource_manager *man;
101 container_of(man->bdev, struct vmw_private, bdev);
102 struct vmwgfx_gmrid_man *gman =106 struct vmwgfx_gmrid_man *gman =
103 kzalloc(sizeof(*gman), GFP_KERNEL);107 kzalloc(sizeof(*gman), GFP_KERNEL);
104 108
105 if (unlikely(!gman))109 if (unlikely(!gman))
106 return -ENOMEM;110 return -ENOMEM;
107 111
112 man = &gman->manager;
113
114 man->func = &vmw_gmrid_manager_func;
115 man->available_caching = TTM_PL_FLAG_CACHED;
116 man->default_caching = TTM_PL_FLAG_CACHED;
117 /* TODO: This is most likely not correct */
118 man->use_tt = true;
119 ttm_resource_manager_init(man, 0);
108 spin_lock_init(&gman->lock);120 spin_lock_init(&gman->lock);
109 gman->used_gmr_pages = 0;121 gman->used_gmr_pages = 0;
110 ida_init(&gman->gmr_ida);122 ida_init(&gman->gmr_ida);
111 123
112 switch (p_size) {124 switch (type) {
113 case VMW_PL_GMR:125 case VMW_PL_GMR:
114 gman->max_gmr_ids = dev_priv->max_gmr_ids;126 gman->max_gmr_ids = dev_priv->max_gmr_ids;
115 gman->max_gmr_pages = dev_priv->max_gmr_pages;127 gman->max_gmr_pages = dev_priv->max_gmr_pages;
@@ -121,32 +133,29 @@ static int vmw_gmrid_man_init(struct ttm_mem_type_manager *man, · 5 unmodified lines
121 default:133 default:
122 BUG();134 BUG();
123 }135 }
124 man->priv = (void *) gman;136 ttm_set_driver_manager(&dev_priv->bdev, type, &gman->manager);
137 ttm_resource_manager_set_used(man, true);
125 return 0;138 return 0;
126}139}
127 140
128static int vmw_gmrid_man_takedown(struct ttm_mem_type_manager *man)141void vmw_gmrid_man_fini(struct vmw_private *dev_priv, int type)
129{142{
130 struct vmwgfx_gmrid_man *gman =143 struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, type);
131 (struct vmwgfx_gmrid_man *)man->priv;144 struct vmwgfx_gmrid_man *gman = to_gmrid_manager(man);
132 145
133 if (gman) {146 ttm_resource_manager_set_used(man, false);
134 ida_destroy(&gman->gmr_ida);147
135 kfree(gman);148 ttm_resource_manager_force_list_clean(&dev_priv->bdev, man);
136 }149
137 return 0;150 ttm_resource_manager_cleanup(man);
138}151
152 ttm_set_driver_manager(&dev_priv->bdev, type, NULL);
153 ida_destroy(&gman->gmr_ida);
154 kfree(gman);
139 155
140static void vmw_gmrid_man_debug(struct ttm_mem_type_manager *man,
141 struct drm_printer *printer)
142{
143 drm_printf(printer, "No debug info available for the GMR id manager\n");
144}156}
145 157
146const struct ttm_mem_type_manager_func vmw_gmrid_manager_func = {158static const struct ttm_resource_manager_func vmw_gmrid_manager_func = {
147 .init = vmw_gmrid_man_init,159 .alloc = vmw_gmrid_man_get_node,
148 .takedown = vmw_gmrid_man_takedown,160 .free = vmw_gmrid_man_put_node,
149 .get_node = vmw_gmrid_man_get_node,
150 .put_node = vmw_gmrid_man_put_node,
151 .debug = vmw_gmrid_man_debug
152};161};
drivers/gpu/drm/vmwgfx/vmwgfx_mob.c+3−57
@@ -238,10 +238,6 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, · 237 unmodified lines
238 unsigned long offset;238 unsigned long offset;
239 unsigned long bo_size;239 unsigned long bo_size;
240 struct vmw_otable *otables = batch->otables;240 struct vmw_otable *otables = batch->otables;
241 struct ttm_operation_ctx ctx = {
242 .interruptible = false,
243 .no_wait_gpu = false
244 };
245 SVGAOTableType i;241 SVGAOTableType i;
246 int ret;242 int ret;
247 243
@@ -255,24 +251,9 @@ static int vmw_otable_batch_setup(struct vmw_private *dev_priv, · 7 unmodified lines
255 bo_size += otables[i].size;251 bo_size += otables[i].size;
256 }252 }
257 253
258 ret = ttm_bo_create(&dev_priv->bdev, bo_size,
259 ttm_bo_type_device,
260 &vmw_sys_ne_placement,
261 0, false, &batch->otable_bo);
262
263 if (unlikely(ret != 0))
264 goto out_no_bo;
265

75 more lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_resource.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_thp.c+45−28

This diff is large: its 137 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c+39−82

This diff is large: its 177 lines aren’t shown here.

drivers/video/fbdev/acornfb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/arcfb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/atmel_lcdfb.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/video/fbdev/aty/radeon_pm.c+3−3

This diff is large: its 23 lines aren’t shown here.

drivers/video/fbdev/cirrusfb.c+2−2

This diff is large: its 14 lines aren’t shown here.

drivers/video/fbdev/controlfb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/core/fbmem.c+6−6

This diff is large: its 54 lines aren’t shown here.

drivers/video/fbdev/fsl-diu-fb.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/video/fbdev/gxt4500.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/i740fb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/offb.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/video/fbdev/omap/lcdc.c+2−2

This diff is large: its 16 lines aren’t shown here.

drivers/video/fbdev/omap/omapfb_main.c+10−10

This diff is large: its 62 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/dss/dispc.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/dss/hdmi4.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/dss/hdmi5.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/omap2/omapfb/omapfb-main.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/pm2fb.c+2−2

This diff is large: its 13 lines aren’t shown here.

drivers/video/fbdev/pvr2fb.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/pxafb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/s3c-fb.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/video/fbdev/sa1100fb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/savage/savagefb_driver.c+1−2

This diff is large: its 10 lines aren’t shown here.

drivers/video/fbdev/sh_mobile_lcdcfb.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/video/fbdev/sm501fb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/tdfxfb.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/video/fbdev/xen-fbfront.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/virtio/Kconfig+7−0

This diff is large: its 12 lines aren’t shown here.

drivers/virtio/Makefile+1−0

This diff is large: its 5 lines aren’t shown here.

drivers/virtio/virtio.c+6−0

This diff is large: its 13 lines aren’t shown here.

drivers/virtio/virtio_dma_buf.c+88−0

This diff is large: its 89 lines aren’t shown here.

include/drm/drm_connector.h+3−0

This diff is large: its 14 lines aren’t shown here.

include/drm/drm_dp_helper.h+8−0

This diff is large: its 22 lines aren’t shown here.

include/drm/drm_mode_config.h+6−0

This diff is large: its 13 lines aren’t shown here.

include/drm/drm_panel.h+11−4

This diff is large: its 43 lines aren’t shown here.

include/drm/ttm/ttm_bo_api.h+11−98

This diff is large: its 155 lines aren’t shown here.

include/drm/ttm/ttm_bo_driver.h+91−264

This diff is large: its 547 lines aren’t shown here.

include/drm/ttm/ttm_resource.h+261−0

This diff is large: its 262 lines aren’t shown here.

include/drm/ttm/ttm_tt.h+5−5

This diff is large: its 40 lines aren’t shown here.

include/linux/fb.h+9−9

This diff is large: its 51 lines aren’t shown here.

include/linux/moduleparam.h+6−1

This diff is large: its 21 lines aren’t shown here.

include/linux/virtio.h+1−0

This diff is large: its 8 lines aren’t shown here.

include/linux/virtio_dma_buf.h+37−0

This diff is large: its 38 lines aren’t shown here.

include/uapi/drm/drm_mode.h+13−8

This diff is large: its 28 lines aren’t shown here.

include/uapi/linux/virtio_gpu.h+19−0

This diff is large: its 45 lines aren’t shown here.

kernel/params.c+9−8

This diff is large: its 24 lines aren’t shown here.