| .. | .. |
|---|
| 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); |
|---|