+static int init_loader_memory(struct drm_device *drm_dev)
+{
+ struct rockchip_drm_private *private = drm_dev->dev_private;
+ struct rockchip_logo *logo;
+ struct device_node *np = drm_dev->dev->of_node;
+ struct device_node *node;
+ unsigned long nr_pages;
+ struct page **pages;
+ struct sg_table *sgt;
+ DEFINE_DMA_ATTRS(attrs);
+ phys_addr_t start, size;
+ struct resource res;
+ int i, ret;
+
+ logo = devm_kmalloc(drm_dev->dev, sizeof(*logo), GFP_KERNEL);
+ if (!logo)
+ return -ENOMEM;
+
+ node = of_parse_phandle(np, "memory-region", 0);
+ if (!node)
+ return -ENOMEM;
+
+ ret = of_address_to_resource(node, 0, &res);
+ if (ret)
+ return ret;
+ start = res.start;
+ size = resource_size(&res);
+ if (!size)
+ return -ENOMEM;
+
+ nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ pages = kmalloc_array(nr_pages, sizeof(*pages), GFP_KERNEL);
+ if (!pages)
+ return -ENOMEM;
+ i = 0;
+ while (i < nr_pages) {
+ pages[i] = phys_to_page(start);
+ start += PAGE_SIZE;
+ i++;
+ }
+ sgt = drm_prime_pages_to_sg(pages, nr_pages);
+ if (IS_ERR(sgt)) {
+ kfree(pages);
+ return PTR_ERR(sgt);
+ }
+
+ dma_set_attr(DMA_ATTR_SKIP_CPU_SYNC, &attrs);
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
+ dma_map_sg_attrs(drm_dev->dev, sgt->sgl, sgt->nents,
+ DMA_TO_DEVICE, &attrs);
+ logo->dma_addr = sg_dma_address(sgt->sgl);
+ logo->sgt = sgt;
+ logo->start = res.start;
+ logo->size = size;
+ logo->count = 0;
+ private->logo = logo;
+
+ return 0;
+}
+