.. | .. |
---|
63 | 63 | #else |
---|
64 | 64 | static bool is_support_iommu = true; |
---|
65 | 65 | #endif |
---|
| 66 | +static bool iommu_reserve_map; |
---|
66 | 67 | static struct drm_driver rockchip_drm_driver; |
---|
67 | 68 | |
---|
68 | 69 | struct rockchip_drm_mode_set { |
---|
.. | .. |
---|
1320 | 1321 | struct rockchip_drm_private *private = drm_dev->dev_private; |
---|
1321 | 1322 | struct iommu_domain_geometry *geometry; |
---|
1322 | 1323 | u64 start, end; |
---|
| 1324 | + int ret = 0; |
---|
1323 | 1325 | |
---|
1324 | 1326 | if (!is_support_iommu) |
---|
1325 | 1327 | return 0; |
---|
.. | .. |
---|
1340 | 1342 | iommu_set_fault_handler(private->domain, rockchip_drm_fault_handler, |
---|
1341 | 1343 | drm_dev); |
---|
1342 | 1344 | |
---|
1343 | | - return 0; |
---|
| 1345 | + if (iommu_reserve_map) { |
---|
| 1346 | + /* |
---|
| 1347 | + * At 32 bit platform size_t maximum value is 0xffffffff, SZ_4G(0x100000000) will be |
---|
| 1348 | + * cliped to 0, so we split into two mapping |
---|
| 1349 | + */ |
---|
| 1350 | + ret = iommu_map(private->domain, 0, 0, (size_t)SZ_2G, |
---|
| 1351 | + IOMMU_WRITE | IOMMU_READ | IOMMU_PRIV); |
---|
| 1352 | + if (ret) |
---|
| 1353 | + dev_err(drm_dev->dev, "failed to create 0-2G pre mapping\n"); |
---|
| 1354 | + |
---|
| 1355 | + ret = iommu_map(private->domain, SZ_2G, SZ_2G, (size_t)SZ_2G, |
---|
| 1356 | + IOMMU_WRITE | IOMMU_READ | IOMMU_PRIV); |
---|
| 1357 | + if (ret) |
---|
| 1358 | + dev_err(drm_dev->dev, "failed to create 2G-4G pre mapping\n"); |
---|
| 1359 | + } |
---|
| 1360 | + |
---|
| 1361 | + return ret; |
---|
1344 | 1362 | } |
---|
1345 | 1363 | |
---|
1346 | 1364 | static void rockchip_iommu_cleanup(struct drm_device *drm_dev) |
---|
.. | .. |
---|
1350 | 1368 | if (!is_support_iommu) |
---|
1351 | 1369 | return; |
---|
1352 | 1370 | |
---|
| 1371 | + if (iommu_reserve_map) { |
---|
| 1372 | + iommu_unmap(private->domain, 0, (size_t)SZ_2G); |
---|
| 1373 | + iommu_unmap(private->domain, SZ_2G, (size_t)SZ_2G); |
---|
| 1374 | + } |
---|
1353 | 1375 | drm_mm_takedown(&private->mm); |
---|
1354 | 1376 | iommu_domain_free(private->domain); |
---|
1355 | 1377 | } |
---|
.. | .. |
---|
1765 | 1787 | if (ret) |
---|
1766 | 1788 | goto err_kms_helper_poll_fini; |
---|
1767 | 1789 | |
---|
1768 | | - drm_for_each_crtc(crtc, drm_dev) { |
---|
1769 | | - struct drm_fb_helper *helper = private->fbdev_helper; |
---|
1770 | | - struct rockchip_crtc_state *s = NULL; |
---|
| 1790 | + if (private->fbdev_helper && private->fbdev_helper->fb) { |
---|
| 1791 | + drm_for_each_crtc(crtc, drm_dev) { |
---|
| 1792 | + struct rockchip_crtc_state *s = NULL; |
---|
1771 | 1793 | |
---|
1772 | | - if (!helper) |
---|
1773 | | - break; |
---|
1774 | | - |
---|
1775 | | - s = to_rockchip_crtc_state(crtc->state); |
---|
1776 | | - if (is_support_hotplug(s->output_type)) |
---|
1777 | | - drm_framebuffer_get(helper->fb); |
---|
| 1794 | + s = to_rockchip_crtc_state(crtc->state); |
---|
| 1795 | + if (is_support_hotplug(s->output_type)) |
---|
| 1796 | + drm_framebuffer_get(private->fbdev_helper->fb); |
---|
| 1797 | + } |
---|
1778 | 1798 | } |
---|
1779 | 1799 | |
---|
1780 | 1800 | drm_dev->mode_config.allow_fb_modifiers = true; |
---|
.. | .. |
---|
2303 | 2323 | } |
---|
2304 | 2324 | |
---|
2305 | 2325 | found = true; |
---|
| 2326 | + iommu_reserve_map |= of_property_read_bool(iommu, "rockchip,reserve-map"); |
---|
2306 | 2327 | |
---|
2307 | 2328 | of_node_put(iommu); |
---|
2308 | 2329 | of_node_put(port); |
---|