From 5165359760ae217f51b1ba401d03ebaa69f63687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=94=98=E7=BD=97=E5=AE=87?= Date: Fri, 30 May 2025 14:55:21 +0800 Subject: [PATCH] bootslot = 2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 甘罗宇 --- linux-6.6/rk3568_patch/kernel.patch | 14502 +++++++++++++------------- 1 file changed, 7251 insertions(+), 7251 deletions(-) diff --git a/linux-6.6/rk3568_patch/kernel.patch b/linux-6.6/rk3568_patch/kernel.patch index 1ff4793..a48856b 100644 --- a/linux-6.6/rk3568_patch/kernel.patch +++ b/linux-6.6/rk3568_patch/kernel.patch @@ -477,7 +477,7 @@ index 000000000..ea315345e --- /dev/null +++ b/Documentation/devicetree/bindings/arm/mali-utgard.txt @@ -0,0 +1,68 @@ -+/* ++/* + * Copyright (C) 2014, 2016-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -485,66 +485,66 @@ index 000000000..ea315345e + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+* ARM Mali-300/400/450 GPU -+ -+Required properties: -+- compatible: -+ At least one of these: "arm,mali-300", "arm,mali-400", "arm,mali-450" -+ Always: "arm,mali-utgard" -+ Mali-450 can also include "arm,mali-400" as it is compatible. -+ - "arm,mali-400", "arm,mali-utgard" for any Mali-400 GPU. -+ - "arm,mali-450", "arm,mali-400", "arm,mali-utgard" for any Mali-450 GPU. -+- reg: -+ Physical base address and length of the GPU's registers. -+- interrupts: -+ - List of all Mali interrupts. -+ - This list must match the number of and the order of entries in -+ interrupt-names. -+- interrupt-names: -+ - IRQPP - Name for PP interrupts. -+ - IRQPPMMU - Name for interrupts from the PP MMU. -+ - IRQPP - Name for the PP broadcast interrupt (Mali-450 only). -+ - IRQGP - Name for the GP interrupt. -+ - IRQGPMMU - Name for the interrupt from the GP MMU. -+ - IRQPMU - Name for the PMU interrupt (If pmu is implemented in HW, it must be contained). -+ -+Optional properties: -+- pmu_domain_config: -+ - If the Mali internal PMU is present and the PMU IRQ is specified in -+ interrupt/interrupt-names ("IRQPMU").This contains the mapping of -+ Mali HW units to the PMU power domain. -+ -Mali Dynamic power domain configuration in sequence from 0-11, like: -+ . -+- pmu-switch-delay: -+ - Only needed if the power gates are connected to the PMU in a high fanout -+ network. This value is the number of Mali clock cycles it takes to -+ enable the power gates and turn on the power mesh. This value will -+ have no effect if a daisy chain implementation is used. -+ -+Platform related properties: -+- clocks: Phandle to clock for Mali utgard device. -+- clock-names: the corresponding names of clock in clocks property. -+- regulator: Phandle to regulator which is power supplier of mali device. -+ -+Example for a Mali400_MP1_PMU device: -+ -+/ { -+ ... -+ -+ gpu@12300000 { -+ compatible = "arm,mali-400", "arm,mali-utgard"; -+ reg = <0x12300000 0x30000>; -+ interrupts = <0 55 4>, <0 56 4>, <0 57 4>, <0 58 4>, <0 59 4>; -+ interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPMU"; -+ -+ pmu_domain_config = <0x1 0x4 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x2 0x0 0x0>; -+ pmu_switch_delay = <0xff>; -+ clocks = , ; -+ clock-names = "mali_parent", "mali"; -+ vdd_g3d-supply = ; -+ }; -+} ++ */ ++* ARM Mali-300/400/450 GPU ++ ++Required properties: ++- compatible: ++ At least one of these: "arm,mali-300", "arm,mali-400", "arm,mali-450" ++ Always: "arm,mali-utgard" ++ Mali-450 can also include "arm,mali-400" as it is compatible. ++ - "arm,mali-400", "arm,mali-utgard" for any Mali-400 GPU. ++ - "arm,mali-450", "arm,mali-400", "arm,mali-utgard" for any Mali-450 GPU. ++- reg: ++ Physical base address and length of the GPU's registers. ++- interrupts: ++ - List of all Mali interrupts. ++ - This list must match the number of and the order of entries in ++ interrupt-names. ++- interrupt-names: ++ - IRQPP - Name for PP interrupts. ++ - IRQPPMMU - Name for interrupts from the PP MMU. ++ - IRQPP - Name for the PP broadcast interrupt (Mali-450 only). ++ - IRQGP - Name for the GP interrupt. ++ - IRQGPMMU - Name for the interrupt from the GP MMU. ++ - IRQPMU - Name for the PMU interrupt (If pmu is implemented in HW, it must be contained). ++ ++Optional properties: ++- pmu_domain_config: ++ - If the Mali internal PMU is present and the PMU IRQ is specified in ++ interrupt/interrupt-names ("IRQPMU").This contains the mapping of ++ Mali HW units to the PMU power domain. ++ -Mali Dynamic power domain configuration in sequence from 0-11, like: ++ . ++- pmu-switch-delay: ++ - Only needed if the power gates are connected to the PMU in a high fanout ++ network. This value is the number of Mali clock cycles it takes to ++ enable the power gates and turn on the power mesh. This value will ++ have no effect if a daisy chain implementation is used. ++ ++Platform related properties: ++- clocks: Phandle to clock for Mali utgard device. ++- clock-names: the corresponding names of clock in clocks property. ++- regulator: Phandle to regulator which is power supplier of mali device. ++ ++Example for a Mali400_MP1_PMU device: ++ ++/ { ++ ... ++ ++ gpu@12300000 { ++ compatible = "arm,mali-400", "arm,mali-utgard"; ++ reg = <0x12300000 0x30000>; ++ interrupts = <0 55 4>, <0 56 4>, <0 57 4>, <0 58 4>, <0 59 4>; ++ interrupt-names = "IRQGP", "IRQGPMMU", "IRQPP0", "IRQPPMMU0", "IRQPMU"; ++ ++ pmu_domain_config = <0x1 0x4 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x2 0x0 0x0>; ++ pmu_switch_delay = <0xff>; ++ clocks = , ; ++ clock-names = "mali_parent", "mali"; ++ vdd_g3d-supply = ; ++ }; ++} diff --git a/Documentation/devicetree/bindings/crypto/rockchip,rk3588-crypto.yaml b/Documentation/devicetree/bindings/crypto/rockchip,rk3588-crypto.yaml new file mode 100644 index 000000000..c01963413 @@ -3743,7 +3743,7 @@ index 000000000..838606964 + +/ { + chosen: chosen { -+ bootargs = "earlycon=uart8250,mmio32,0xfe660000 console=ttyFIQ0 ohos.boot.eng_mode=on root=PARTUUID=614e0000-0000 hardware=rk3568 default_boot_device=fe310000.sdhci rw rootwait ohos.required_mount.system=/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required ohos.required_mount.vendor=/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required ohos.required_mount.misc=/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required ohos.required_mount.bootctrl=/dev/block/platform/fe310000.sdhci/by-name/bootctrl@none@none@none@wait,required"; ++ bootargs = "bootslots=2 earlycon=uart8250,mmio32,0xfe660000 console=ttyFIQ0 ohos.boot.eng_mode=on root=PARTUUID=614e0000-0000 hardware=rk3568 default_boot_device=fe310000.sdhci rw rootwait ohos.required_mount.system=/dev/block/platform/fe310000.sdhci/by-name/system@/usr@ext4@ro,barrier=1@wait,required ohos.required_mount.vendor=/dev/block/platform/fe310000.sdhci/by-name/vendor@/vendor@ext4@ro,barrier=1@wait,required ohos.required_mount.misc=/dev/block/platform/fe310000.sdhci/by-name/misc@none@none@none@wait,required ohos.required_mount.bootctrl=/dev/block/platform/fe310000.sdhci/by-name/bootctrl@none@none@none@wait,required"; + }; + + fiq-debugger { @@ -312182,789 +312182,789 @@ index 000000000..cd9b6d2f7 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_cow.c @@ -0,0 +1,776 @@ -+/* -+ * Copyright (C) 2013-2017 ARM Limited. All rights reserved. -+ * -+ * This program is free software and is provided to you under the terms of the GNU General Public License version 2 -+ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. -+ * -+ * A copy of the licence is included with the program, and can also be obtained from Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_ARM -+#include -+#endif -+#include -+ -+#include "mali_memory.h" -+#include "mali_kernel_common.h" -+#include "mali_uk_types.h" -+#include "mali_osk.h" -+#include "mali_kernel_linux.h" -+#include "mali_memory_cow.h" -+#include "mali_memory_block_alloc.h" -+#include "mali_memory_swap_alloc.h" -+ -+/** -+* allocate pages for COW backend and flush cache -+*/ -+static struct page *mali_mem_cow_alloc_page(void) -+ -+{ -+ mali_mem_os_mem os_mem; -+ struct mali_page_node *node; -+ struct page *new_page; -+ -+ int ret = 0; -+ /* allocate pages from os mem */ -+ ret = mali_mem_os_alloc_pages(&os_mem, _MALI_OSK_MALI_PAGE_SIZE); -+ -+ if (ret) { -+ return NULL; -+ } -+ -+ MALI_DEBUG_ASSERT(1 == os_mem.count); -+ -+ node = _MALI_OSK_CONTAINER_OF(os_mem.pages.next, struct mali_page_node, list); -+ new_page = node->page; -+ node->page = NULL; -+ list_del(&node->list); -+ kfree(node); -+ -+ return new_page; -+} -+ -+ -+static struct list_head *_mali_memory_cow_get_node_list(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size) -+{ -+ MALI_DEBUG_ASSERT(MALI_MEM_OS == target_bk->type || MALI_MEM_COW == target_bk->type || -+ MALI_MEM_BLOCK == target_bk->type || MALI_MEM_SWAP == target_bk->type); -+ -+ if (MALI_MEM_OS == target_bk->type) { -+ MALI_DEBUG_ASSERT(&target_bk->os_mem); -+ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->os_mem.count); -+ return &target_bk->os_mem.pages; -+ } else if (MALI_MEM_COW == target_bk->type) { -+ MALI_DEBUG_ASSERT(&target_bk->cow_mem); -+ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->cow_mem.count); -+ return &target_bk->cow_mem.pages; -+ } else if (MALI_MEM_BLOCK == target_bk->type) { -+ MALI_DEBUG_ASSERT(&target_bk->block_mem); -+ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->block_mem.count); -+ return &target_bk->block_mem.pfns; -+ } else if (MALI_MEM_SWAP == target_bk->type) { -+ MALI_DEBUG_ASSERT(&target_bk->swap_mem); -+ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->swap_mem.count); -+ return &target_bk->swap_mem.pages; -+ } -+ -+ return NULL; -+} -+ -+/** -+* Do COW for os memory - support do COW for memory from bank memory -+* The range_start/size can be zero, which means it will call cow_modify_range -+* latter. -+* This function allocate new pages for COW backend from os mem for a modified range -+* It will keep the page which not in the modified range and Add ref to it -+* -+* @target_bk - target allocation's backend(the allocation need to do COW) -+* @target_offset - the offset in target allocation to do COW(for support COW a memory allocated from memory_bank, 4K align) -+* @target_size - size of target allocation to do COW (for support memory bank) -+* @backend -COW backend -+* @range_start - offset of modified range (4K align) -+* @range_size - size of modified range -+*/ -+_mali_osk_errcode_t mali_memory_cow_os_memory(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size, -+ mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size) -+{ -+ mali_mem_cow *cow = &backend->cow_mem; -+ struct mali_page_node *m_page, *m_tmp, *page_node; -+ int target_page = 0; -+ struct page *new_page; -+ struct list_head *pages = NULL; -+ -+ pages = _mali_memory_cow_get_node_list(target_bk, target_offset, target_size); -+ -+ if (NULL == pages) { -+ MALI_DEBUG_PRINT_ERROR(("No memory page need to cow ! \n")); -+ return _MALI_OSK_ERR_FAULT; -+ } -+ -+ MALI_DEBUG_ASSERT(0 == cow->count); -+ -+ INIT_LIST_HEAD(&cow->pages); -+ mutex_lock(&target_bk->mutex); -+ list_for_each_entry_safe(m_page, m_tmp, pages, list) { -+ /* add page from (target_offset,target_offset+size) to cow backend */ -+ if ((target_page >= target_offset / _MALI_OSK_MALI_PAGE_SIZE) && -+ (target_page < ((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE))) { -+ -+ /* allocate a new page node, alway use OS memory for COW */ -+ page_node = _mali_page_node_allocate(MALI_PAGE_NODE_OS); -+ -+ if (NULL == page_node) { -+ mutex_unlock(&target_bk->mutex); -+ goto error; -+ } -+ -+ INIT_LIST_HEAD(&page_node->list); -+ -+ /* check if in the modified range*/ -+ if ((cow->count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && -+ (cow->count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { -+ /* need to allocate a new page */ -+ /* To simplify the case, All COW memory is allocated from os memory ?*/ -+ new_page = mali_mem_cow_alloc_page(); -+ -+ if (NULL == new_page) { -+ kfree(page_node); -+ mutex_unlock(&target_bk->mutex); -+ goto error; -+ } -+ -+ _mali_page_node_add_page(page_node, new_page); -+ } else { -+ /*Add Block memory case*/ -+ if (m_page->type != MALI_PAGE_NODE_BLOCK) { -+ _mali_page_node_add_page(page_node, m_page->page); -+ } else { -+ page_node->type = MALI_PAGE_NODE_BLOCK; -+ _mali_page_node_add_block_item(page_node, m_page->blk_it); -+ } -+ -+ /* add ref to this page */ -+ _mali_page_node_ref(m_page); -+ } -+ -+ /* add it to COW backend page list */ -+ list_add_tail(&page_node->list, &cow->pages); -+ cow->count++; -+ } -+ target_page++; -+ } -+ mutex_unlock(&target_bk->mutex); -+ return _MALI_OSK_ERR_OK; -+error: -+ mali_mem_cow_release(backend, MALI_FALSE); -+ return _MALI_OSK_ERR_FAULT; -+} -+ -+_mali_osk_errcode_t mali_memory_cow_swap_memory(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size, -+ mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size) -+{ -+ mali_mem_cow *cow = &backend->cow_mem; -+ struct mali_page_node *m_page, *m_tmp, *page_node; -+ int target_page = 0; -+ struct mali_swap_item *swap_item; -+ struct list_head *pages = NULL; -+ -+ pages = _mali_memory_cow_get_node_list(target_bk, target_offset, target_size); -+ if (NULL == pages) { -+ MALI_DEBUG_PRINT_ERROR(("No swap memory page need to cow ! \n")); -+ return _MALI_OSK_ERR_FAULT; -+ } -+ -+ MALI_DEBUG_ASSERT(0 == cow->count); -+ -+ INIT_LIST_HEAD(&cow->pages); -+ mutex_lock(&target_bk->mutex); -+ -+ backend->flags |= MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN; -+ -+ list_for_each_entry_safe(m_page, m_tmp, pages, list) { -+ /* add page from (target_offset,target_offset+size) to cow backend */ -+ if ((target_page >= target_offset / _MALI_OSK_MALI_PAGE_SIZE) && -+ (target_page < ((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE))) { -+ -+ /* allocate a new page node, use swap memory for COW memory swap cowed flag. */ -+ page_node = _mali_page_node_allocate(MALI_PAGE_NODE_SWAP); -+ -+ if (NULL == page_node) { -+ mutex_unlock(&target_bk->mutex); -+ goto error; -+ } -+ -+ /* check if in the modified range*/ -+ if ((cow->count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && -+ (cow->count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { -+ /* need to allocate a new page */ -+ /* To simplify the case, All COW memory is allocated from os memory ?*/ -+ swap_item = mali_mem_swap_alloc_swap_item(); -+ -+ if (NULL == swap_item) { -+ kfree(page_node); -+ mutex_unlock(&target_bk->mutex); -+ goto error; -+ } -+ -+ swap_item->idx = mali_mem_swap_idx_alloc(); -+ -+ if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == swap_item->idx) { -+ MALI_DEBUG_PRINT(1, ("Failed to allocate swap index in swap CoW.\n")); -+ kfree(page_node); -+ kfree(swap_item); -+ mutex_unlock(&target_bk->mutex); -+ goto error; -+ } -+ -+ _mali_page_node_add_swap_item(page_node, swap_item); -+ } else { -+ _mali_page_node_add_swap_item(page_node, m_page->swap_it); -+ -+ /* add ref to this page */ -+ _mali_page_node_ref(m_page); -+ } -+ -+ list_add_tail(&page_node->list, &cow->pages); -+ cow->count++; -+ } -+ target_page++; -+ } -+ mutex_unlock(&target_bk->mutex); -+ -+ return _MALI_OSK_ERR_OK; -+error: -+ mali_mem_swap_release(backend, MALI_FALSE); -+ return _MALI_OSK_ERR_FAULT; -+ -+} -+ -+ -+_mali_osk_errcode_t _mali_mem_put_page_node(mali_page_node *node) -+{ -+ if (node->type == MALI_PAGE_NODE_OS) { -+ return mali_mem_os_put_page(node->page); -+ } else if (node->type == MALI_PAGE_NODE_BLOCK) { -+ return mali_mem_block_unref_node(node); -+ } else if (node->type == MALI_PAGE_NODE_SWAP) { -+ return _mali_mem_swap_put_page_node(node); -+ } else -+ MALI_DEBUG_ASSERT(0); -+ return _MALI_OSK_ERR_FAULT; -+} -+ -+ -+/** -+* Modify a range of a exist COW backend -+* @backend -COW backend -+* @range_start - offset of modified range (4K align) -+* @range_size - size of modified range(in byte) -+*/ -+_mali_osk_errcode_t mali_memory_cow_modify_range(mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size) -+{ -+ mali_mem_allocation *alloc = NULL; -+ struct mali_session_data *session; -+ mali_mem_cow *cow = &backend->cow_mem; -+ struct mali_page_node *m_page, *m_tmp; -+ LIST_HEAD(pages); -+ struct page *new_page; -+ u32 count = 0; -+ s32 change_pages_nr = 0; -+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_OK; -+ -+ if (range_start % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ if (range_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ -+ alloc = backend->mali_allocation; -+ MALI_DEBUG_ASSERT_POINTER(alloc); -+ -+ session = alloc->session; -+ MALI_DEBUG_ASSERT_POINTER(session); -+ -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == backend->type); -+ MALI_DEBUG_ASSERT(((range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE) <= cow->count); -+ -+ mutex_lock(&backend->mutex); -+ -+ /* free pages*/ -+ list_for_each_entry_safe(m_page, m_tmp, &cow->pages, list) { -+ -+ /* check if in the modified range*/ -+ if ((count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && -+ (count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { -+ if (MALI_PAGE_NODE_SWAP != m_page->type) { -+ new_page = mali_mem_cow_alloc_page(); -+ -+ if (NULL == new_page) { -+ goto error; -+ } -+ if (1 != _mali_page_node_get_ref_count(m_page)) -+ change_pages_nr++; -+ /* unref old page*/ -+ _mali_osk_mutex_wait(session->cow_lock); -+ if (_mali_mem_put_page_node(m_page)) { -+ __free_page(new_page); -+ _mali_osk_mutex_signal(session->cow_lock); -+ goto error; -+ } -+ _mali_osk_mutex_signal(session->cow_lock); -+ /* add new page*/ -+ /* always use OS for COW*/ -+ m_page->type = MALI_PAGE_NODE_OS; -+ _mali_page_node_add_page(m_page, new_page); -+ } else { -+ struct mali_swap_item *swap_item; -+ -+ swap_item = mali_mem_swap_alloc_swap_item(); -+ -+ if (NULL == swap_item) { -+ goto error; -+ } -+ -+ swap_item->idx = mali_mem_swap_idx_alloc(); -+ -+ if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == swap_item->idx) { -+ MALI_DEBUG_PRINT(1, ("Failed to allocate swap index in swap CoW modify range.\n")); -+ kfree(swap_item); -+ goto error; -+ } -+ -+ if (1 != _mali_page_node_get_ref_count(m_page)) { -+ change_pages_nr++; -+ } -+ -+ if (_mali_mem_put_page_node(m_page)) { -+ mali_mem_swap_free_swap_item(swap_item); -+ goto error; -+ } -+ -+ _mali_page_node_add_swap_item(m_page, swap_item); -+ } -+ } -+ count++; -+ } -+ cow->change_pages_nr = change_pages_nr; -+ -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == alloc->type); -+ -+ /* ZAP cpu mapping(modified range), and do cpu mapping here if need */ -+ if (NULL != alloc->cpu_mapping.vma) { -+ MALI_DEBUG_ASSERT(0 != alloc->backend_handle); -+ MALI_DEBUG_ASSERT(NULL != alloc->cpu_mapping.vma); -+ MALI_DEBUG_ASSERT(alloc->cpu_mapping.vma->vm_end - alloc->cpu_mapping.vma->vm_start >= range_size); -+ -+ if (MALI_MEM_BACKEND_FLAG_SWAP_COWED != (backend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED)) { -+ zap_vma_ptes(alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size); -+ -+ ret = mali_mem_cow_cpu_map_pages_locked(backend, alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size / _MALI_OSK_MALI_PAGE_SIZE); -+ -+ if (unlikely(ret != _MALI_OSK_ERR_OK)) { -+ MALI_DEBUG_PRINT(2, ("mali_memory_cow_modify_range: cpu mapping failed !\n")); -+ ret = _MALI_OSK_ERR_FAULT; -+ } -+ } else { -+ /* used to trigger page fault for swappable cowed memory. */ -+ vm_flags_set(alloc->cpu_mapping.vma, VM_PFNMAP); -+ vm_flags_set(alloc->cpu_mapping.vma, VM_MIXEDMAP); -+ -+ zap_vma_ptes(alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size); -+ /* delete this flag to let swappble is ummapped regard to stauct page not page frame. */ -+ vm_flags_clear(alloc->cpu_mapping.vma, VM_PFNMAP); -+ vm_flags_clear(alloc->cpu_mapping.vma, VM_MIXEDMAP); -+ } -+ } -+ -+error: -+ mutex_unlock(&backend->mutex); -+ return ret; -+ -+} -+ -+ -+/** -+* Allocate pages for COW backend -+* @alloc -allocation for COW allocation -+* @target_bk - target allocation's backend(the allocation need to do COW) -+* @target_offset - the offset in target allocation to do COW(for support COW a memory allocated from memory_bank, 4K align) -+* @target_size - size of target allocation to do COW (for support memory bank)(in byte) -+* @backend -COW backend -+* @range_start - offset of modified range (4K align) -+* @range_size - size of modified range(in byte) -+*/ -+_mali_osk_errcode_t mali_memory_do_cow(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size, -+ mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size) -+{ -+ struct mali_session_data *session = backend->mali_allocation->session; -+ -+ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); -+ -+ /* size & offset must be a multiple of the system page size */ -+ if (target_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ if (range_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ if (target_offset % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ if (range_start % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); -+ -+ /* check backend type */ -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == backend->type); -+ -+ switch (target_bk->type) { -+ case MALI_MEM_OS: -+ case MALI_MEM_BLOCK: -+ return mali_memory_cow_os_memory(target_bk, target_offset, target_size, backend, range_start, range_size); -+ break; -+ case MALI_MEM_COW: -+ if (backend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED) { -+ return mali_memory_cow_swap_memory(target_bk, target_offset, target_size, backend, range_start, range_size); -+ } else { -+ return mali_memory_cow_os_memory(target_bk, target_offset, target_size, backend, range_start, range_size); -+ } -+ break; -+ case MALI_MEM_SWAP: -+ return mali_memory_cow_swap_memory(target_bk, target_offset, target_size, backend, range_start, range_size); -+ break; -+ case MALI_MEM_EXTERNAL: -+ /*NOT support yet*/ -+ MALI_DEBUG_PRINT_ERROR(("External physical memory not supported ! \n")); -+ return _MALI_OSK_ERR_UNSUPPORTED; -+ break; -+ case MALI_MEM_DMA_BUF: -+ /*NOT support yet*/ -+ MALI_DEBUG_PRINT_ERROR(("DMA buffer not supported ! \n")); -+ return _MALI_OSK_ERR_UNSUPPORTED; -+ break; -+ case MALI_MEM_UMP: -+ /*NOT support yet*/ -+ MALI_DEBUG_PRINT_ERROR(("UMP buffer not supported ! \n")); -+ return _MALI_OSK_ERR_UNSUPPORTED; -+ break; -+ default: -+ /*Not support yet*/ -+ MALI_DEBUG_PRINT_ERROR(("Invalid memory type not supported ! \n")); -+ return _MALI_OSK_ERR_UNSUPPORTED; -+ break; -+ } -+ return _MALI_OSK_ERR_OK; -+} -+ -+ -+/** -+* Map COW backend memory to mali -+* Support OS/BLOCK for mali_page_node -+*/ -+int mali_mem_cow_mali_map(mali_mem_backend *mem_bkend, u32 range_start, u32 range_size) -+{ -+ mali_mem_allocation *cow_alloc; -+ struct mali_page_node *m_page; -+ struct mali_session_data *session; -+ struct mali_page_directory *pagedir; -+ u32 virt, start; -+ -+ cow_alloc = mem_bkend->mali_allocation; -+ virt = cow_alloc->mali_vma_node.vm_node.start; -+ start = virt; -+ -+ MALI_DEBUG_ASSERT_POINTER(mem_bkend); -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); -+ MALI_DEBUG_ASSERT_POINTER(cow_alloc); -+ -+ session = cow_alloc->session; -+ pagedir = session->page_directory; -+ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); -+ list_for_each_entry(m_page, &mem_bkend->cow_mem.pages, list) { -+ if ((virt - start >= range_start) && (virt - start < range_start + range_size)) { -+ dma_addr_t phys = _mali_page_node_get_dma_addr(m_page); -+#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) -+ MALI_DEBUG_ASSERT(0 == (phys >> 32)); -+#endif -+ mali_mmu_pagedir_update(pagedir, virt, (mali_dma_addr)phys, -+ MALI_MMU_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT); -+ } -+ virt += MALI_MMU_PAGE_SIZE; -+ } -+ return 0; -+} -+ -+/** -+* Map COW backend to cpu -+* support OS/BLOCK memory -+*/ -+int mali_mem_cow_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma) -+{ -+ mali_mem_cow *cow = &mem_bkend->cow_mem; -+ struct mali_page_node *m_page; -+ int ret; -+ unsigned long addr = vma->vm_start; -+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_COW); -+ -+ list_for_each_entry(m_page, &cow->pages, list) { -+ /* We should use vm_insert_page, but it does a dcache -+ * flush which makes it way slower than remap_pfn_range or vmf_insert_pfn. -+ ret = vm_insert_page(vma, addr, page); -+ */ -+ ret = vmf_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page)); -+ -+ if (unlikely(VM_FAULT_NOPAGE != ret)) { -+ return -EFAULT; -+ } -+ addr += _MALI_OSK_MALI_PAGE_SIZE; -+ } -+ -+ return 0; -+} -+ -+/** -+* Map some pages(COW backend) to CPU vma@vaddr -+*@ mem_bkend - COW backend -+*@ vma -+*@ vaddr -start CPU vaddr mapped to -+*@ num - max number of pages to map to CPU vaddr -+*/ -+_mali_osk_errcode_t mali_mem_cow_cpu_map_pages_locked(mali_mem_backend *mem_bkend, -+ struct vm_area_struct *vma, -+ unsigned long vaddr, -+ int num) -+{ -+ mali_mem_cow *cow = &mem_bkend->cow_mem; -+ struct mali_page_node *m_page; -+ int ret; -+ int offset; -+ int count ; -+ unsigned long vstart = vma->vm_start; -+ count = 0; -+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_COW); -+ MALI_DEBUG_ASSERT(0 == vaddr % _MALI_OSK_MALI_PAGE_SIZE); -+ MALI_DEBUG_ASSERT(0 == vstart % _MALI_OSK_MALI_PAGE_SIZE); -+ offset = (vaddr - vstart) / _MALI_OSK_MALI_PAGE_SIZE; -+ -+ list_for_each_entry(m_page, &cow->pages, list) { -+ if ((count >= offset) && (count < offset + num)) { -+ ret = vmf_insert_pfn(vma, vaddr, _mali_page_node_get_pfn(m_page)); -+ -+ if (unlikely(VM_FAULT_NOPAGE != ret)) { -+ if (count == offset) { -+ return _MALI_OSK_ERR_FAULT; -+ } else { -+ /* ret is EBUSY when page isn't in modify range, but now it's OK*/ -+ return _MALI_OSK_ERR_OK; -+ } -+ } -+ vaddr += _MALI_OSK_MALI_PAGE_SIZE; -+ } -+ count++; -+ } -+ return _MALI_OSK_ERR_OK; -+} -+ -+/** -+* Release COW backend memory -+* free it directly(put_page--unref page), not put into pool -+*/ -+u32 mali_mem_cow_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped) -+{ -+ mali_mem_allocation *alloc; -+ struct mali_session_data *session; -+ u32 free_pages_nr = 0; -+ MALI_DEBUG_ASSERT_POINTER(mem_bkend); -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); -+ alloc = mem_bkend->mali_allocation; -+ MALI_DEBUG_ASSERT_POINTER(alloc); -+ -+ session = alloc->session; -+ MALI_DEBUG_ASSERT_POINTER(session); -+ -+ if (MALI_MEM_BACKEND_FLAG_SWAP_COWED != (MALI_MEM_BACKEND_FLAG_SWAP_COWED & mem_bkend->flags)) { -+ /* Unmap the memory from the mali virtual address space. */ -+ if (MALI_TRUE == is_mali_mapped) -+ mali_mem_os_mali_unmap(alloc); -+ /* free cow backend list*/ -+ _mali_osk_mutex_wait(session->cow_lock); -+ free_pages_nr = mali_mem_os_free(&mem_bkend->cow_mem.pages, mem_bkend->cow_mem.count, MALI_TRUE); -+ _mali_osk_mutex_signal(session->cow_lock); -+ -+ free_pages_nr += mali_mem_block_free_list(&mem_bkend->cow_mem.pages); -+ -+ MALI_DEBUG_ASSERT(list_empty(&mem_bkend->cow_mem.pages)); -+ } else { -+ free_pages_nr = mali_mem_swap_release(mem_bkend, is_mali_mapped); -+ } -+ -+ -+ MALI_DEBUG_PRINT(4, ("COW Mem free : allocated size = 0x%x, free size = 0x%x\n", mem_bkend->cow_mem.count * _MALI_OSK_MALI_PAGE_SIZE, -+ free_pages_nr * _MALI_OSK_MALI_PAGE_SIZE)); -+ -+ mem_bkend->cow_mem.count = 0; -+ return free_pages_nr; -+} -+ -+ -+/* Dst node could os node or swap node. */ -+void _mali_mem_cow_copy_page(mali_page_node *src_node, mali_page_node *dst_node) -+{ -+ void *dst, *src; -+ struct page *dst_page; -+ dma_addr_t dma_addr; -+ -+ MALI_DEBUG_ASSERT(src_node != NULL); -+ MALI_DEBUG_ASSERT(dst_node != NULL); -+ MALI_DEBUG_ASSERT(dst_node->type == MALI_PAGE_NODE_OS -+ || dst_node->type == MALI_PAGE_NODE_SWAP); -+ -+ if (dst_node->type == MALI_PAGE_NODE_OS) { -+ dst_page = dst_node->page; -+ } else { -+ dst_page = dst_node->swap_it->page; -+ } -+ -+ dma_unmap_page(&mali_platform_device->dev, _mali_page_node_get_dma_addr(dst_node), -+ _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); -+ -+ /* map it , and copy the content*/ -+ dst = kmap_atomic(dst_page); -+ -+ if (src_node->type == MALI_PAGE_NODE_OS || -+ src_node->type == MALI_PAGE_NODE_SWAP) { -+ struct page *src_page; -+ -+ if (src_node->type == MALI_PAGE_NODE_OS) { -+ src_page = src_node->page; -+ } else { -+ src_page = src_node->swap_it->page; -+ } -+ -+ /* Clear and invaliate cache */ -+ /* In ARM architecture, speculative read may pull stale data into L1 cache -+ * for kernel linear mapping page table. DMA_BIDIRECTIONAL could -+ * invalidate the L1 cache so that following read get the latest data -+ */ -+ dma_unmap_page(&mali_platform_device->dev, _mali_page_node_get_dma_addr(src_node), -+ _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); -+ -+ src = kmap_atomic(src_page); -+ memcpy(dst, src , _MALI_OSK_MALI_PAGE_SIZE); -+ kunmap_atomic(src); -+ dma_addr = dma_map_page(&mali_platform_device->dev, src_page, -+ 0, _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); -+ -+ if (src_node->type == MALI_PAGE_NODE_SWAP) { -+ src_node->swap_it->dma_addr = dma_addr; -+ } -+ } else if (src_node->type == MALI_PAGE_NODE_BLOCK) { -+ /* -+ * use ioremap to map src for BLOCK memory -+ */ -+ src = ioremap(_mali_page_node_get_dma_addr(src_node), _MALI_OSK_MALI_PAGE_SIZE); -+ memcpy(dst, src , _MALI_OSK_MALI_PAGE_SIZE); -+ iounmap(src); -+ } -+ kunmap_atomic(dst); -+ dma_addr = dma_map_page(&mali_platform_device->dev, dst_page, -+ 0, _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); -+ -+ if (dst_node->type == MALI_PAGE_NODE_SWAP) { -+ dst_node->swap_it->dma_addr = dma_addr; -+ } -+} -+ -+ -+/* -+* allocate page on demand when CPU access it, -+* THis used in page fault handler -+*/ -+_mali_osk_errcode_t mali_mem_cow_allocate_on_demand(mali_mem_backend *mem_bkend, u32 offset_page) -+{ -+ struct page *new_page = NULL; -+ struct mali_page_node *new_node = NULL; -+ int i = 0; -+ struct mali_page_node *m_page, *found_node = NULL; -+ struct mali_session_data *session = NULL; -+ mali_mem_cow *cow = &mem_bkend->cow_mem; -+ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); -+ MALI_DEBUG_ASSERT(offset_page < mem_bkend->size / _MALI_OSK_MALI_PAGE_SIZE); -+ MALI_DEBUG_PRINT(4, ("mali_mem_cow_allocate_on_demand !, offset_page =0x%x\n", offset_page)); -+ -+ /* allocate new page here */ -+ new_page = mali_mem_cow_alloc_page(); -+ if (!new_page) -+ return _MALI_OSK_ERR_NOMEM; -+ -+ new_node = _mali_page_node_allocate(MALI_PAGE_NODE_OS); -+ if (!new_node) { -+ __free_page(new_page); -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ -+ /* find the page in backend*/ -+ list_for_each_entry(m_page, &cow->pages, list) { -+ if (i == offset_page) { -+ found_node = m_page; -+ break; -+ } -+ i++; -+ } -+ MALI_DEBUG_ASSERT(found_node); -+ if (NULL == found_node) { -+ __free_page(new_page); -+ kfree(new_node); -+ return _MALI_OSK_ERR_ITEM_NOT_FOUND; -+ } -+ -+ _mali_page_node_add_page(new_node, new_page); -+ -+ /* Copy the src page's content to new page */ -+ _mali_mem_cow_copy_page(found_node, new_node); -+ -+ MALI_DEBUG_ASSERT_POINTER(mem_bkend->mali_allocation); -+ session = mem_bkend->mali_allocation->session; -+ MALI_DEBUG_ASSERT_POINTER(session); -+ if (1 != _mali_page_node_get_ref_count(found_node)) { -+ atomic_add(1, &session->mali_mem_allocated_pages); -+ if (atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE > session->max_mali_mem_allocated_size) { -+ session->max_mali_mem_allocated_size = atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE; -+ } -+ mem_bkend->cow_mem.change_pages_nr++; -+ } -+ -+ _mali_osk_mutex_wait(session->cow_lock); -+ if (_mali_mem_put_page_node(found_node)) { -+ __free_page(new_page); -+ kfree(new_node); -+ _mali_osk_mutex_signal(session->cow_lock); -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ _mali_osk_mutex_signal(session->cow_lock); -+ -+ list_replace(&found_node->list, &new_node->list); -+ -+ kfree(found_node); -+ -+ /* map to GPU side*/ -+ _mali_osk_mutex_wait(session->memory_lock); -+ mali_mem_cow_mali_map(mem_bkend, offset_page * _MALI_OSK_MALI_PAGE_SIZE, _MALI_OSK_MALI_PAGE_SIZE); -+ _mali_osk_mutex_signal(session->memory_lock); -+ return _MALI_OSK_ERR_OK; -+} ++/* ++ * Copyright (C) 2013-2017 ARM Limited. All rights reserved. ++ * ++ * This program is free software and is provided to you under the terms of the GNU General Public License version 2 ++ * as published by the Free Software Foundation, and any use by you of this program is subject to the terms of such GNU licence. ++ * ++ * A copy of the licence is included with the program, and can also be obtained from Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_ARM ++#include ++#endif ++#include ++ ++#include "mali_memory.h" ++#include "mali_kernel_common.h" ++#include "mali_uk_types.h" ++#include "mali_osk.h" ++#include "mali_kernel_linux.h" ++#include "mali_memory_cow.h" ++#include "mali_memory_block_alloc.h" ++#include "mali_memory_swap_alloc.h" ++ ++/** ++* allocate pages for COW backend and flush cache ++*/ ++static struct page *mali_mem_cow_alloc_page(void) ++ ++{ ++ mali_mem_os_mem os_mem; ++ struct mali_page_node *node; ++ struct page *new_page; ++ ++ int ret = 0; ++ /* allocate pages from os mem */ ++ ret = mali_mem_os_alloc_pages(&os_mem, _MALI_OSK_MALI_PAGE_SIZE); ++ ++ if (ret) { ++ return NULL; ++ } ++ ++ MALI_DEBUG_ASSERT(1 == os_mem.count); ++ ++ node = _MALI_OSK_CONTAINER_OF(os_mem.pages.next, struct mali_page_node, list); ++ new_page = node->page; ++ node->page = NULL; ++ list_del(&node->list); ++ kfree(node); ++ ++ return new_page; ++} ++ ++ ++static struct list_head *_mali_memory_cow_get_node_list(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size) ++{ ++ MALI_DEBUG_ASSERT(MALI_MEM_OS == target_bk->type || MALI_MEM_COW == target_bk->type || ++ MALI_MEM_BLOCK == target_bk->type || MALI_MEM_SWAP == target_bk->type); ++ ++ if (MALI_MEM_OS == target_bk->type) { ++ MALI_DEBUG_ASSERT(&target_bk->os_mem); ++ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->os_mem.count); ++ return &target_bk->os_mem.pages; ++ } else if (MALI_MEM_COW == target_bk->type) { ++ MALI_DEBUG_ASSERT(&target_bk->cow_mem); ++ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->cow_mem.count); ++ return &target_bk->cow_mem.pages; ++ } else if (MALI_MEM_BLOCK == target_bk->type) { ++ MALI_DEBUG_ASSERT(&target_bk->block_mem); ++ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->block_mem.count); ++ return &target_bk->block_mem.pfns; ++ } else if (MALI_MEM_SWAP == target_bk->type) { ++ MALI_DEBUG_ASSERT(&target_bk->swap_mem); ++ MALI_DEBUG_ASSERT(((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE) <= target_bk->swap_mem.count); ++ return &target_bk->swap_mem.pages; ++ } ++ ++ return NULL; ++} ++ ++/** ++* Do COW for os memory - support do COW for memory from bank memory ++* The range_start/size can be zero, which means it will call cow_modify_range ++* latter. ++* This function allocate new pages for COW backend from os mem for a modified range ++* It will keep the page which not in the modified range and Add ref to it ++* ++* @target_bk - target allocation's backend(the allocation need to do COW) ++* @target_offset - the offset in target allocation to do COW(for support COW a memory allocated from memory_bank, 4K align) ++* @target_size - size of target allocation to do COW (for support memory bank) ++* @backend -COW backend ++* @range_start - offset of modified range (4K align) ++* @range_size - size of modified range ++*/ ++_mali_osk_errcode_t mali_memory_cow_os_memory(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size, ++ mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size) ++{ ++ mali_mem_cow *cow = &backend->cow_mem; ++ struct mali_page_node *m_page, *m_tmp, *page_node; ++ int target_page = 0; ++ struct page *new_page; ++ struct list_head *pages = NULL; ++ ++ pages = _mali_memory_cow_get_node_list(target_bk, target_offset, target_size); ++ ++ if (NULL == pages) { ++ MALI_DEBUG_PRINT_ERROR(("No memory page need to cow ! \n")); ++ return _MALI_OSK_ERR_FAULT; ++ } ++ ++ MALI_DEBUG_ASSERT(0 == cow->count); ++ ++ INIT_LIST_HEAD(&cow->pages); ++ mutex_lock(&target_bk->mutex); ++ list_for_each_entry_safe(m_page, m_tmp, pages, list) { ++ /* add page from (target_offset,target_offset+size) to cow backend */ ++ if ((target_page >= target_offset / _MALI_OSK_MALI_PAGE_SIZE) && ++ (target_page < ((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE))) { ++ ++ /* allocate a new page node, alway use OS memory for COW */ ++ page_node = _mali_page_node_allocate(MALI_PAGE_NODE_OS); ++ ++ if (NULL == page_node) { ++ mutex_unlock(&target_bk->mutex); ++ goto error; ++ } ++ ++ INIT_LIST_HEAD(&page_node->list); ++ ++ /* check if in the modified range*/ ++ if ((cow->count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && ++ (cow->count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { ++ /* need to allocate a new page */ ++ /* To simplify the case, All COW memory is allocated from os memory ?*/ ++ new_page = mali_mem_cow_alloc_page(); ++ ++ if (NULL == new_page) { ++ kfree(page_node); ++ mutex_unlock(&target_bk->mutex); ++ goto error; ++ } ++ ++ _mali_page_node_add_page(page_node, new_page); ++ } else { ++ /*Add Block memory case*/ ++ if (m_page->type != MALI_PAGE_NODE_BLOCK) { ++ _mali_page_node_add_page(page_node, m_page->page); ++ } else { ++ page_node->type = MALI_PAGE_NODE_BLOCK; ++ _mali_page_node_add_block_item(page_node, m_page->blk_it); ++ } ++ ++ /* add ref to this page */ ++ _mali_page_node_ref(m_page); ++ } ++ ++ /* add it to COW backend page list */ ++ list_add_tail(&page_node->list, &cow->pages); ++ cow->count++; ++ } ++ target_page++; ++ } ++ mutex_unlock(&target_bk->mutex); ++ return _MALI_OSK_ERR_OK; ++error: ++ mali_mem_cow_release(backend, MALI_FALSE); ++ return _MALI_OSK_ERR_FAULT; ++} ++ ++_mali_osk_errcode_t mali_memory_cow_swap_memory(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size, ++ mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size) ++{ ++ mali_mem_cow *cow = &backend->cow_mem; ++ struct mali_page_node *m_page, *m_tmp, *page_node; ++ int target_page = 0; ++ struct mali_swap_item *swap_item; ++ struct list_head *pages = NULL; ++ ++ pages = _mali_memory_cow_get_node_list(target_bk, target_offset, target_size); ++ if (NULL == pages) { ++ MALI_DEBUG_PRINT_ERROR(("No swap memory page need to cow ! \n")); ++ return _MALI_OSK_ERR_FAULT; ++ } ++ ++ MALI_DEBUG_ASSERT(0 == cow->count); ++ ++ INIT_LIST_HEAD(&cow->pages); ++ mutex_lock(&target_bk->mutex); ++ ++ backend->flags |= MALI_MEM_BACKEND_FLAG_UNSWAPPED_IN; ++ ++ list_for_each_entry_safe(m_page, m_tmp, pages, list) { ++ /* add page from (target_offset,target_offset+size) to cow backend */ ++ if ((target_page >= target_offset / _MALI_OSK_MALI_PAGE_SIZE) && ++ (target_page < ((target_size + target_offset) / _MALI_OSK_MALI_PAGE_SIZE))) { ++ ++ /* allocate a new page node, use swap memory for COW memory swap cowed flag. */ ++ page_node = _mali_page_node_allocate(MALI_PAGE_NODE_SWAP); ++ ++ if (NULL == page_node) { ++ mutex_unlock(&target_bk->mutex); ++ goto error; ++ } ++ ++ /* check if in the modified range*/ ++ if ((cow->count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && ++ (cow->count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { ++ /* need to allocate a new page */ ++ /* To simplify the case, All COW memory is allocated from os memory ?*/ ++ swap_item = mali_mem_swap_alloc_swap_item(); ++ ++ if (NULL == swap_item) { ++ kfree(page_node); ++ mutex_unlock(&target_bk->mutex); ++ goto error; ++ } ++ ++ swap_item->idx = mali_mem_swap_idx_alloc(); ++ ++ if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == swap_item->idx) { ++ MALI_DEBUG_PRINT(1, ("Failed to allocate swap index in swap CoW.\n")); ++ kfree(page_node); ++ kfree(swap_item); ++ mutex_unlock(&target_bk->mutex); ++ goto error; ++ } ++ ++ _mali_page_node_add_swap_item(page_node, swap_item); ++ } else { ++ _mali_page_node_add_swap_item(page_node, m_page->swap_it); ++ ++ /* add ref to this page */ ++ _mali_page_node_ref(m_page); ++ } ++ ++ list_add_tail(&page_node->list, &cow->pages); ++ cow->count++; ++ } ++ target_page++; ++ } ++ mutex_unlock(&target_bk->mutex); ++ ++ return _MALI_OSK_ERR_OK; ++error: ++ mali_mem_swap_release(backend, MALI_FALSE); ++ return _MALI_OSK_ERR_FAULT; ++ ++} ++ ++ ++_mali_osk_errcode_t _mali_mem_put_page_node(mali_page_node *node) ++{ ++ if (node->type == MALI_PAGE_NODE_OS) { ++ return mali_mem_os_put_page(node->page); ++ } else if (node->type == MALI_PAGE_NODE_BLOCK) { ++ return mali_mem_block_unref_node(node); ++ } else if (node->type == MALI_PAGE_NODE_SWAP) { ++ return _mali_mem_swap_put_page_node(node); ++ } else ++ MALI_DEBUG_ASSERT(0); ++ return _MALI_OSK_ERR_FAULT; ++} ++ ++ ++/** ++* Modify a range of a exist COW backend ++* @backend -COW backend ++* @range_start - offset of modified range (4K align) ++* @range_size - size of modified range(in byte) ++*/ ++_mali_osk_errcode_t mali_memory_cow_modify_range(mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size) ++{ ++ mali_mem_allocation *alloc = NULL; ++ struct mali_session_data *session; ++ mali_mem_cow *cow = &backend->cow_mem; ++ struct mali_page_node *m_page, *m_tmp; ++ LIST_HEAD(pages); ++ struct page *new_page; ++ u32 count = 0; ++ s32 change_pages_nr = 0; ++ _mali_osk_errcode_t ret = _MALI_OSK_ERR_OK; ++ ++ if (range_start % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ if (range_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ ++ alloc = backend->mali_allocation; ++ MALI_DEBUG_ASSERT_POINTER(alloc); ++ ++ session = alloc->session; ++ MALI_DEBUG_ASSERT_POINTER(session); ++ ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == backend->type); ++ MALI_DEBUG_ASSERT(((range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE) <= cow->count); ++ ++ mutex_lock(&backend->mutex); ++ ++ /* free pages*/ ++ list_for_each_entry_safe(m_page, m_tmp, &cow->pages, list) { ++ ++ /* check if in the modified range*/ ++ if ((count >= range_start / _MALI_OSK_MALI_PAGE_SIZE) && ++ (count < (range_start + range_size) / _MALI_OSK_MALI_PAGE_SIZE)) { ++ if (MALI_PAGE_NODE_SWAP != m_page->type) { ++ new_page = mali_mem_cow_alloc_page(); ++ ++ if (NULL == new_page) { ++ goto error; ++ } ++ if (1 != _mali_page_node_get_ref_count(m_page)) ++ change_pages_nr++; ++ /* unref old page*/ ++ _mali_osk_mutex_wait(session->cow_lock); ++ if (_mali_mem_put_page_node(m_page)) { ++ __free_page(new_page); ++ _mali_osk_mutex_signal(session->cow_lock); ++ goto error; ++ } ++ _mali_osk_mutex_signal(session->cow_lock); ++ /* add new page*/ ++ /* always use OS for COW*/ ++ m_page->type = MALI_PAGE_NODE_OS; ++ _mali_page_node_add_page(m_page, new_page); ++ } else { ++ struct mali_swap_item *swap_item; ++ ++ swap_item = mali_mem_swap_alloc_swap_item(); ++ ++ if (NULL == swap_item) { ++ goto error; ++ } ++ ++ swap_item->idx = mali_mem_swap_idx_alloc(); ++ ++ if (_MALI_OSK_BITMAP_INVALIDATE_INDEX == swap_item->idx) { ++ MALI_DEBUG_PRINT(1, ("Failed to allocate swap index in swap CoW modify range.\n")); ++ kfree(swap_item); ++ goto error; ++ } ++ ++ if (1 != _mali_page_node_get_ref_count(m_page)) { ++ change_pages_nr++; ++ } ++ ++ if (_mali_mem_put_page_node(m_page)) { ++ mali_mem_swap_free_swap_item(swap_item); ++ goto error; ++ } ++ ++ _mali_page_node_add_swap_item(m_page, swap_item); ++ } ++ } ++ count++; ++ } ++ cow->change_pages_nr = change_pages_nr; ++ ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == alloc->type); ++ ++ /* ZAP cpu mapping(modified range), and do cpu mapping here if need */ ++ if (NULL != alloc->cpu_mapping.vma) { ++ MALI_DEBUG_ASSERT(0 != alloc->backend_handle); ++ MALI_DEBUG_ASSERT(NULL != alloc->cpu_mapping.vma); ++ MALI_DEBUG_ASSERT(alloc->cpu_mapping.vma->vm_end - alloc->cpu_mapping.vma->vm_start >= range_size); ++ ++ if (MALI_MEM_BACKEND_FLAG_SWAP_COWED != (backend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED)) { ++ zap_vma_ptes(alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size); ++ ++ ret = mali_mem_cow_cpu_map_pages_locked(backend, alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size / _MALI_OSK_MALI_PAGE_SIZE); ++ ++ if (unlikely(ret != _MALI_OSK_ERR_OK)) { ++ MALI_DEBUG_PRINT(2, ("mali_memory_cow_modify_range: cpu mapping failed !\n")); ++ ret = _MALI_OSK_ERR_FAULT; ++ } ++ } else { ++ /* used to trigger page fault for swappable cowed memory. */ ++ vm_flags_set(alloc->cpu_mapping.vma, VM_PFNMAP); ++ vm_flags_set(alloc->cpu_mapping.vma, VM_MIXEDMAP); ++ ++ zap_vma_ptes(alloc->cpu_mapping.vma, alloc->cpu_mapping.vma->vm_start + range_start, range_size); ++ /* delete this flag to let swappble is ummapped regard to stauct page not page frame. */ ++ vm_flags_clear(alloc->cpu_mapping.vma, VM_PFNMAP); ++ vm_flags_clear(alloc->cpu_mapping.vma, VM_MIXEDMAP); ++ } ++ } ++ ++error: ++ mutex_unlock(&backend->mutex); ++ return ret; ++ ++} ++ ++ ++/** ++* Allocate pages for COW backend ++* @alloc -allocation for COW allocation ++* @target_bk - target allocation's backend(the allocation need to do COW) ++* @target_offset - the offset in target allocation to do COW(for support COW a memory allocated from memory_bank, 4K align) ++* @target_size - size of target allocation to do COW (for support memory bank)(in byte) ++* @backend -COW backend ++* @range_start - offset of modified range (4K align) ++* @range_size - size of modified range(in byte) ++*/ ++_mali_osk_errcode_t mali_memory_do_cow(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size, ++ mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size) ++{ ++ struct mali_session_data *session = backend->mali_allocation->session; ++ ++ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); ++ ++ /* size & offset must be a multiple of the system page size */ ++ if (target_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ if (range_size % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ if (target_offset % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ if (range_start % _MALI_OSK_MALI_PAGE_SIZE) MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); ++ ++ /* check backend type */ ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == backend->type); ++ ++ switch (target_bk->type) { ++ case MALI_MEM_OS: ++ case MALI_MEM_BLOCK: ++ return mali_memory_cow_os_memory(target_bk, target_offset, target_size, backend, range_start, range_size); ++ break; ++ case MALI_MEM_COW: ++ if (backend->flags & MALI_MEM_BACKEND_FLAG_SWAP_COWED) { ++ return mali_memory_cow_swap_memory(target_bk, target_offset, target_size, backend, range_start, range_size); ++ } else { ++ return mali_memory_cow_os_memory(target_bk, target_offset, target_size, backend, range_start, range_size); ++ } ++ break; ++ case MALI_MEM_SWAP: ++ return mali_memory_cow_swap_memory(target_bk, target_offset, target_size, backend, range_start, range_size); ++ break; ++ case MALI_MEM_EXTERNAL: ++ /*NOT support yet*/ ++ MALI_DEBUG_PRINT_ERROR(("External physical memory not supported ! \n")); ++ return _MALI_OSK_ERR_UNSUPPORTED; ++ break; ++ case MALI_MEM_DMA_BUF: ++ /*NOT support yet*/ ++ MALI_DEBUG_PRINT_ERROR(("DMA buffer not supported ! \n")); ++ return _MALI_OSK_ERR_UNSUPPORTED; ++ break; ++ case MALI_MEM_UMP: ++ /*NOT support yet*/ ++ MALI_DEBUG_PRINT_ERROR(("UMP buffer not supported ! \n")); ++ return _MALI_OSK_ERR_UNSUPPORTED; ++ break; ++ default: ++ /*Not support yet*/ ++ MALI_DEBUG_PRINT_ERROR(("Invalid memory type not supported ! \n")); ++ return _MALI_OSK_ERR_UNSUPPORTED; ++ break; ++ } ++ return _MALI_OSK_ERR_OK; ++} ++ ++ ++/** ++* Map COW backend memory to mali ++* Support OS/BLOCK for mali_page_node ++*/ ++int mali_mem_cow_mali_map(mali_mem_backend *mem_bkend, u32 range_start, u32 range_size) ++{ ++ mali_mem_allocation *cow_alloc; ++ struct mali_page_node *m_page; ++ struct mali_session_data *session; ++ struct mali_page_directory *pagedir; ++ u32 virt, start; ++ ++ cow_alloc = mem_bkend->mali_allocation; ++ virt = cow_alloc->mali_vma_node.vm_node.start; ++ start = virt; ++ ++ MALI_DEBUG_ASSERT_POINTER(mem_bkend); ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); ++ MALI_DEBUG_ASSERT_POINTER(cow_alloc); ++ ++ session = cow_alloc->session; ++ pagedir = session->page_directory; ++ MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_INVALID_ARGS); ++ list_for_each_entry(m_page, &mem_bkend->cow_mem.pages, list) { ++ if ((virt - start >= range_start) && (virt - start < range_start + range_size)) { ++ dma_addr_t phys = _mali_page_node_get_dma_addr(m_page); ++#if defined(CONFIG_ARCH_DMA_ADDR_T_64BIT) ++ MALI_DEBUG_ASSERT(0 == (phys >> 32)); ++#endif ++ mali_mmu_pagedir_update(pagedir, virt, (mali_dma_addr)phys, ++ MALI_MMU_PAGE_SIZE, MALI_MMU_FLAGS_DEFAULT); ++ } ++ virt += MALI_MMU_PAGE_SIZE; ++ } ++ return 0; ++} ++ ++/** ++* Map COW backend to cpu ++* support OS/BLOCK memory ++*/ ++int mali_mem_cow_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma) ++{ ++ mali_mem_cow *cow = &mem_bkend->cow_mem; ++ struct mali_page_node *m_page; ++ int ret; ++ unsigned long addr = vma->vm_start; ++ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_COW); ++ ++ list_for_each_entry(m_page, &cow->pages, list) { ++ /* We should use vm_insert_page, but it does a dcache ++ * flush which makes it way slower than remap_pfn_range or vmf_insert_pfn. ++ ret = vm_insert_page(vma, addr, page); ++ */ ++ ret = vmf_insert_pfn(vma, addr, _mali_page_node_get_pfn(m_page)); ++ ++ if (unlikely(VM_FAULT_NOPAGE != ret)) { ++ return -EFAULT; ++ } ++ addr += _MALI_OSK_MALI_PAGE_SIZE; ++ } ++ ++ return 0; ++} ++ ++/** ++* Map some pages(COW backend) to CPU vma@vaddr ++*@ mem_bkend - COW backend ++*@ vma ++*@ vaddr -start CPU vaddr mapped to ++*@ num - max number of pages to map to CPU vaddr ++*/ ++_mali_osk_errcode_t mali_mem_cow_cpu_map_pages_locked(mali_mem_backend *mem_bkend, ++ struct vm_area_struct *vma, ++ unsigned long vaddr, ++ int num) ++{ ++ mali_mem_cow *cow = &mem_bkend->cow_mem; ++ struct mali_page_node *m_page; ++ int ret; ++ int offset; ++ int count ; ++ unsigned long vstart = vma->vm_start; ++ count = 0; ++ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_COW); ++ MALI_DEBUG_ASSERT(0 == vaddr % _MALI_OSK_MALI_PAGE_SIZE); ++ MALI_DEBUG_ASSERT(0 == vstart % _MALI_OSK_MALI_PAGE_SIZE); ++ offset = (vaddr - vstart) / _MALI_OSK_MALI_PAGE_SIZE; ++ ++ list_for_each_entry(m_page, &cow->pages, list) { ++ if ((count >= offset) && (count < offset + num)) { ++ ret = vmf_insert_pfn(vma, vaddr, _mali_page_node_get_pfn(m_page)); ++ ++ if (unlikely(VM_FAULT_NOPAGE != ret)) { ++ if (count == offset) { ++ return _MALI_OSK_ERR_FAULT; ++ } else { ++ /* ret is EBUSY when page isn't in modify range, but now it's OK*/ ++ return _MALI_OSK_ERR_OK; ++ } ++ } ++ vaddr += _MALI_OSK_MALI_PAGE_SIZE; ++ } ++ count++; ++ } ++ return _MALI_OSK_ERR_OK; ++} ++ ++/** ++* Release COW backend memory ++* free it directly(put_page--unref page), not put into pool ++*/ ++u32 mali_mem_cow_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped) ++{ ++ mali_mem_allocation *alloc; ++ struct mali_session_data *session; ++ u32 free_pages_nr = 0; ++ MALI_DEBUG_ASSERT_POINTER(mem_bkend); ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); ++ alloc = mem_bkend->mali_allocation; ++ MALI_DEBUG_ASSERT_POINTER(alloc); ++ ++ session = alloc->session; ++ MALI_DEBUG_ASSERT_POINTER(session); ++ ++ if (MALI_MEM_BACKEND_FLAG_SWAP_COWED != (MALI_MEM_BACKEND_FLAG_SWAP_COWED & mem_bkend->flags)) { ++ /* Unmap the memory from the mali virtual address space. */ ++ if (MALI_TRUE == is_mali_mapped) ++ mali_mem_os_mali_unmap(alloc); ++ /* free cow backend list*/ ++ _mali_osk_mutex_wait(session->cow_lock); ++ free_pages_nr = mali_mem_os_free(&mem_bkend->cow_mem.pages, mem_bkend->cow_mem.count, MALI_TRUE); ++ _mali_osk_mutex_signal(session->cow_lock); ++ ++ free_pages_nr += mali_mem_block_free_list(&mem_bkend->cow_mem.pages); ++ ++ MALI_DEBUG_ASSERT(list_empty(&mem_bkend->cow_mem.pages)); ++ } else { ++ free_pages_nr = mali_mem_swap_release(mem_bkend, is_mali_mapped); ++ } ++ ++ ++ MALI_DEBUG_PRINT(4, ("COW Mem free : allocated size = 0x%x, free size = 0x%x\n", mem_bkend->cow_mem.count * _MALI_OSK_MALI_PAGE_SIZE, ++ free_pages_nr * _MALI_OSK_MALI_PAGE_SIZE)); ++ ++ mem_bkend->cow_mem.count = 0; ++ return free_pages_nr; ++} ++ ++ ++/* Dst node could os node or swap node. */ ++void _mali_mem_cow_copy_page(mali_page_node *src_node, mali_page_node *dst_node) ++{ ++ void *dst, *src; ++ struct page *dst_page; ++ dma_addr_t dma_addr; ++ ++ MALI_DEBUG_ASSERT(src_node != NULL); ++ MALI_DEBUG_ASSERT(dst_node != NULL); ++ MALI_DEBUG_ASSERT(dst_node->type == MALI_PAGE_NODE_OS ++ || dst_node->type == MALI_PAGE_NODE_SWAP); ++ ++ if (dst_node->type == MALI_PAGE_NODE_OS) { ++ dst_page = dst_node->page; ++ } else { ++ dst_page = dst_node->swap_it->page; ++ } ++ ++ dma_unmap_page(&mali_platform_device->dev, _mali_page_node_get_dma_addr(dst_node), ++ _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); ++ ++ /* map it , and copy the content*/ ++ dst = kmap_atomic(dst_page); ++ ++ if (src_node->type == MALI_PAGE_NODE_OS || ++ src_node->type == MALI_PAGE_NODE_SWAP) { ++ struct page *src_page; ++ ++ if (src_node->type == MALI_PAGE_NODE_OS) { ++ src_page = src_node->page; ++ } else { ++ src_page = src_node->swap_it->page; ++ } ++ ++ /* Clear and invaliate cache */ ++ /* In ARM architecture, speculative read may pull stale data into L1 cache ++ * for kernel linear mapping page table. DMA_BIDIRECTIONAL could ++ * invalidate the L1 cache so that following read get the latest data ++ */ ++ dma_unmap_page(&mali_platform_device->dev, _mali_page_node_get_dma_addr(src_node), ++ _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); ++ ++ src = kmap_atomic(src_page); ++ memcpy(dst, src , _MALI_OSK_MALI_PAGE_SIZE); ++ kunmap_atomic(src); ++ dma_addr = dma_map_page(&mali_platform_device->dev, src_page, ++ 0, _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); ++ ++ if (src_node->type == MALI_PAGE_NODE_SWAP) { ++ src_node->swap_it->dma_addr = dma_addr; ++ } ++ } else if (src_node->type == MALI_PAGE_NODE_BLOCK) { ++ /* ++ * use ioremap to map src for BLOCK memory ++ */ ++ src = ioremap(_mali_page_node_get_dma_addr(src_node), _MALI_OSK_MALI_PAGE_SIZE); ++ memcpy(dst, src , _MALI_OSK_MALI_PAGE_SIZE); ++ iounmap(src); ++ } ++ kunmap_atomic(dst); ++ dma_addr = dma_map_page(&mali_platform_device->dev, dst_page, ++ 0, _MALI_OSK_MALI_PAGE_SIZE, DMA_BIDIRECTIONAL); ++ ++ if (dst_node->type == MALI_PAGE_NODE_SWAP) { ++ dst_node->swap_it->dma_addr = dma_addr; ++ } ++} ++ ++ ++/* ++* allocate page on demand when CPU access it, ++* THis used in page fault handler ++*/ ++_mali_osk_errcode_t mali_mem_cow_allocate_on_demand(mali_mem_backend *mem_bkend, u32 offset_page) ++{ ++ struct page *new_page = NULL; ++ struct mali_page_node *new_node = NULL; ++ int i = 0; ++ struct mali_page_node *m_page, *found_node = NULL; ++ struct mali_session_data *session = NULL; ++ mali_mem_cow *cow = &mem_bkend->cow_mem; ++ MALI_DEBUG_ASSERT(MALI_MEM_COW == mem_bkend->type); ++ MALI_DEBUG_ASSERT(offset_page < mem_bkend->size / _MALI_OSK_MALI_PAGE_SIZE); ++ MALI_DEBUG_PRINT(4, ("mali_mem_cow_allocate_on_demand !, offset_page =0x%x\n", offset_page)); ++ ++ /* allocate new page here */ ++ new_page = mali_mem_cow_alloc_page(); ++ if (!new_page) ++ return _MALI_OSK_ERR_NOMEM; ++ ++ new_node = _mali_page_node_allocate(MALI_PAGE_NODE_OS); ++ if (!new_node) { ++ __free_page(new_page); ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ ++ /* find the page in backend*/ ++ list_for_each_entry(m_page, &cow->pages, list) { ++ if (i == offset_page) { ++ found_node = m_page; ++ break; ++ } ++ i++; ++ } ++ MALI_DEBUG_ASSERT(found_node); ++ if (NULL == found_node) { ++ __free_page(new_page); ++ kfree(new_node); ++ return _MALI_OSK_ERR_ITEM_NOT_FOUND; ++ } ++ ++ _mali_page_node_add_page(new_node, new_page); ++ ++ /* Copy the src page's content to new page */ ++ _mali_mem_cow_copy_page(found_node, new_node); ++ ++ MALI_DEBUG_ASSERT_POINTER(mem_bkend->mali_allocation); ++ session = mem_bkend->mali_allocation->session; ++ MALI_DEBUG_ASSERT_POINTER(session); ++ if (1 != _mali_page_node_get_ref_count(found_node)) { ++ atomic_add(1, &session->mali_mem_allocated_pages); ++ if (atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE > session->max_mali_mem_allocated_size) { ++ session->max_mali_mem_allocated_size = atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE; ++ } ++ mem_bkend->cow_mem.change_pages_nr++; ++ } ++ ++ _mali_osk_mutex_wait(session->cow_lock); ++ if (_mali_mem_put_page_node(found_node)) { ++ __free_page(new_page); ++ kfree(new_node); ++ _mali_osk_mutex_signal(session->cow_lock); ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ _mali_osk_mutex_signal(session->cow_lock); ++ ++ list_replace(&found_node->list, &new_node->list); ++ ++ kfree(found_node); ++ ++ /* map to GPU side*/ ++ _mali_osk_mutex_wait(session->memory_lock); ++ mali_mem_cow_mali_map(mem_bkend, offset_page * _MALI_OSK_MALI_PAGE_SIZE, _MALI_OSK_MALI_PAGE_SIZE); ++ _mali_osk_mutex_signal(session->memory_lock); ++ return _MALI_OSK_ERR_OK; ++} diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_cow.h b/drivers/gpu/arm/mali400/mali/linux/mali_memory_cow.h new file mode 100644 index 000000000..5f83a37fc --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_cow.h @@ -0,0 +1,48 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -312972,53 +312972,53 @@ index 000000000..5f83a37fc + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#ifndef __MALI_MEMORY_COW_H__ -+#define __MALI_MEMORY_COW_H__ -+ -+#include "mali_osk.h" -+#include "mali_session.h" -+#include "mali_memory_types.h" -+ -+int mali_mem_cow_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma); -+_mali_osk_errcode_t mali_mem_cow_cpu_map_pages_locked(mali_mem_backend *mem_bkend, -+ struct vm_area_struct *vma, -+ unsigned long vaddr, -+ int num); -+ -+_mali_osk_errcode_t mali_memory_do_cow(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size, -+ mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size); -+ -+_mali_osk_errcode_t mali_memory_cow_modify_range(mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size); -+ -+_mali_osk_errcode_t mali_memory_cow_os_memory(mali_mem_backend *target_bk, -+ u32 target_offset, -+ u32 target_size, -+ mali_mem_backend *backend, -+ u32 range_start, -+ u32 range_size); -+ -+void _mali_mem_cow_copy_page(mali_page_node *src_node, mali_page_node *dst_node); -+ -+int mali_mem_cow_mali_map(mali_mem_backend *mem_bkend, u32 range_start, u32 range_size); -+u32 mali_mem_cow_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped); -+_mali_osk_errcode_t mali_mem_cow_allocate_on_demand(mali_mem_backend *mem_bkend, u32 offset_page); -+#endif -+ ++ */ ++ ++#ifndef __MALI_MEMORY_COW_H__ ++#define __MALI_MEMORY_COW_H__ ++ ++#include "mali_osk.h" ++#include "mali_session.h" ++#include "mali_memory_types.h" ++ ++int mali_mem_cow_cpu_map(mali_mem_backend *mem_bkend, struct vm_area_struct *vma); ++_mali_osk_errcode_t mali_mem_cow_cpu_map_pages_locked(mali_mem_backend *mem_bkend, ++ struct vm_area_struct *vma, ++ unsigned long vaddr, ++ int num); ++ ++_mali_osk_errcode_t mali_memory_do_cow(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size, ++ mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size); ++ ++_mali_osk_errcode_t mali_memory_cow_modify_range(mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size); ++ ++_mali_osk_errcode_t mali_memory_cow_os_memory(mali_mem_backend *target_bk, ++ u32 target_offset, ++ u32 target_size, ++ mali_mem_backend *backend, ++ u32 range_start, ++ u32 range_size); ++ ++void _mali_mem_cow_copy_page(mali_page_node *src_node, mali_page_node *dst_node); ++ ++int mali_mem_cow_mali_map(mali_mem_backend *mem_bkend, u32 range_start, u32 range_size); ++u32 mali_mem_cow_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped); ++_mali_osk_errcode_t mali_mem_cow_allocate_on_demand(mali_mem_backend *mem_bkend, u32 offset_page); ++#endif ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.c b/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.c new file mode 100644 index 000000000..a9db577cb --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.c @@ -0,0 +1,262 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -313026,267 +313026,267 @@ index 000000000..a9db577cb + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_ARM -+#include -+#endif -+#include -+ -+#include "mali_memory.h" -+#include "mali_kernel_common.h" -+#include "mali_uk_types.h" -+#include "mali_osk.h" -+#include "mali_kernel_linux.h" -+#include "mali_memory_defer_bind.h" -+#include "mali_executor.h" -+#include "mali_osk.h" -+#include "mali_scheduler.h" -+#include "mali_gp_job.h" -+ -+mali_defer_bind_manager *mali_dmem_man = NULL; -+ -+static u32 mali_dmem_get_gp_varying_size(struct mali_gp_job *gp_job) -+{ -+ return gp_job->required_varying_memsize / _MALI_OSK_MALI_PAGE_SIZE; -+} -+ -+_mali_osk_errcode_t mali_mem_defer_bind_manager_init(void) -+{ -+ mali_dmem_man = _mali_osk_calloc(1, sizeof(struct mali_defer_bind_manager)); -+ if (!mali_dmem_man) -+ return _MALI_OSK_ERR_NOMEM; -+ -+ atomic_set(&mali_dmem_man->num_used_pages, 0); -+ atomic_set(&mali_dmem_man->num_dmem, 0); -+ -+ return _MALI_OSK_ERR_OK; -+} -+ -+ -+void mali_mem_defer_bind_manager_destory(void) -+{ -+ if (mali_dmem_man) { -+ MALI_DEBUG_ASSERT(0 == atomic_read(&mali_dmem_man->num_dmem)); -+ kfree(mali_dmem_man); -+ } -+ mali_dmem_man = NULL; -+} -+ -+ -+/*allocate pages from OS memory*/ -+_mali_osk_errcode_t mali_mem_defer_alloc_mem(u32 require, struct mali_session_data *session, mali_defer_mem_block *dblock) -+{ -+ int retval = 0; -+ u32 num_pages = require; -+ mali_mem_os_mem os_mem; -+ -+ retval = mali_mem_os_alloc_pages(&os_mem, num_pages * _MALI_OSK_MALI_PAGE_SIZE); -+ -+ /* add to free pages list */ -+ if (0 == retval) { -+ MALI_DEBUG_PRINT(4, ("mali_mem_defer_alloc_mem ,,*** pages allocate = 0x%x \n", num_pages)); -+ list_splice(&os_mem.pages, &dblock->free_pages); -+ atomic_add(os_mem.count, &dblock->num_free_pages); -+ atomic_add(os_mem.count, &session->mali_mem_allocated_pages); -+ if (atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE > session->max_mali_mem_allocated_size) { -+ session->max_mali_mem_allocated_size = atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE; -+ } -+ return _MALI_OSK_ERR_OK; -+ } else -+ return _MALI_OSK_ERR_FAULT; -+} -+ -+_mali_osk_errcode_t mali_mem_prepare_mem_for_job(struct mali_gp_job *next_gp_job, mali_defer_mem_block *dblock) -+{ -+ u32 require_page; -+ -+ if (!next_gp_job) -+ return _MALI_OSK_ERR_FAULT; -+ -+ require_page = mali_dmem_get_gp_varying_size(next_gp_job); -+ -+ MALI_DEBUG_PRINT(4, ("mali_mem_defer_prepare_mem_work, require alloc page 0x%x\n", -+ require_page)); -+ /* allocate more pages from OS */ -+ if (_MALI_OSK_ERR_OK != mali_mem_defer_alloc_mem(require_page, next_gp_job->session, dblock)) { -+ MALI_DEBUG_PRINT(1, ("ERROR##mali_mem_defer_prepare_mem_work, allocate page failed!!")); -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ -+ next_gp_job->bind_flag = MALI_DEFER_BIND_MEMORY_PREPARED; -+ -+ return _MALI_OSK_ERR_OK; -+} -+ -+ -+/* do preparetion for allocation before defer bind */ -+_mali_osk_errcode_t mali_mem_defer_bind_allocation_prepare(mali_mem_allocation *alloc, struct list_head *list, u32 *required_varying_memsize) -+{ -+ mali_mem_backend *mem_bkend = NULL; -+ struct mali_backend_bind_list *bk_list = _mali_osk_calloc(1, sizeof(struct mali_backend_bind_list)); -+ if (NULL == bk_list) -+ return _MALI_OSK_ERR_FAULT; -+ -+ INIT_LIST_HEAD(&bk_list->node); -+ /* Get backend memory */ -+ mutex_lock(&mali_idr_mutex); -+ if (!(mem_bkend = idr_find(&mali_backend_idr, alloc->backend_handle))) { -+ MALI_DEBUG_PRINT(1, ("Can't find memory backend in defer bind!\n")); -+ mutex_unlock(&mali_idr_mutex); -+ _mali_osk_free(bk_list); -+ return _MALI_OSK_ERR_FAULT; -+ } -+ mutex_unlock(&mali_idr_mutex); -+ -+ /* If the mem backend has already been bound, no need to bind again.*/ -+ if (mem_bkend->os_mem.count > 0) { -+ _mali_osk_free(bk_list); -+ return _MALI_OSK_ERR_OK; -+ } -+ -+ MALI_DEBUG_PRINT(4, ("bind_allocation_prepare:: allocation =%x vaddr=0x%x!\n", alloc, alloc->mali_vma_node.vm_node.start)); -+ -+ INIT_LIST_HEAD(&mem_bkend->os_mem.pages); -+ -+ bk_list->bkend = mem_bkend; -+ bk_list->vaddr = alloc->mali_vma_node.vm_node.start; -+ bk_list->session = alloc->session; -+ bk_list->page_num = mem_bkend->size / _MALI_OSK_MALI_PAGE_SIZE; -+ *required_varying_memsize += mem_bkend->size; -+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_OS); -+ -+ /* add to job to do list */ -+ list_add(&bk_list->node, list); -+ -+ return _MALI_OSK_ERR_OK; -+} -+ -+ -+ -+/* bind phyiscal memory to allocation -+This function will be called in IRQ handler*/ -+static _mali_osk_errcode_t mali_mem_defer_bind_allocation(struct mali_backend_bind_list *bk_node, -+ struct list_head *pages) -+{ -+ struct mali_session_data *session = bk_node->session; -+ mali_mem_backend *mem_bkend = bk_node->bkend; -+ MALI_DEBUG_PRINT(4, ("mali_mem_defer_bind_allocation, bind bkend = %x page num=0x%x vaddr=%x session=%x\n", mem_bkend, bk_node->page_num, bk_node->vaddr, session)); -+ -+ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_OS); -+ list_splice(pages, &mem_bkend->os_mem.pages); -+ mem_bkend->os_mem.count = bk_node->page_num; -+ -+ if (mem_bkend->type == MALI_MEM_OS) { -+ mali_mem_os_mali_map(&mem_bkend->os_mem, session, bk_node->vaddr, 0, -+ mem_bkend->os_mem.count, MALI_MMU_FLAGS_DEFAULT); -+ } -+ smp_wmb(); -+ bk_node->flag = MALI_DEFER_BIND_MEMORY_BINDED; -+ mem_bkend->flags &= ~MALI_MEM_BACKEND_FLAG_NOT_BINDED; -+ mem_bkend->flags |= MALI_MEM_BACKEND_FLAG_BINDED; -+ return _MALI_OSK_ERR_OK; -+} -+ -+ -+static struct list_head *mali_mem_defer_get_free_page_list(u32 count, struct list_head *pages, mali_defer_mem_block *dblock) -+{ -+ int i = 0; -+ struct mali_page_node *m_page, *m_tmp; -+ -+ if (atomic_read(&dblock->num_free_pages) < count) { -+ return NULL; -+ } else { -+ list_for_each_entry_safe(m_page, m_tmp, &dblock->free_pages, list) { -+ if (i < count) { -+ list_move_tail(&m_page->list, pages); -+ } else { -+ break; -+ } -+ i++; -+ } -+ MALI_DEBUG_ASSERT(i == count); -+ atomic_sub(count, &dblock->num_free_pages); -+ return pages; -+ } -+} -+ -+ -+/* called in job start IOCTL to bind physical memory for each allocations -+@ bk_list backend list to do defer bind -+@ pages page list to do this bind -+@ count number of pages -+*/ -+_mali_osk_errcode_t mali_mem_defer_bind(struct mali_gp_job *gp, -+ struct mali_defer_mem_block *dmem_block) -+{ -+ struct mali_defer_mem *dmem = NULL; -+ struct mali_backend_bind_list *bkn, *bkn_tmp; -+ LIST_HEAD(pages); -+ -+ if (gp->required_varying_memsize != (atomic_read(&dmem_block->num_free_pages) * _MALI_OSK_MALI_PAGE_SIZE)) { -+ MALI_DEBUG_PRINT_ERROR(("#BIND: The memsize of varying buffer not match to the pagesize of the dmem_block!!## \n")); -+ return _MALI_OSK_ERR_FAULT; -+ } -+ -+ MALI_DEBUG_PRINT(4, ("#BIND: GP job=%x## \n", gp)); -+ dmem = (mali_defer_mem *)_mali_osk_calloc(1, sizeof(struct mali_defer_mem)); -+ if (dmem) { -+ INIT_LIST_HEAD(&dmem->node); -+ gp->dmem = dmem; -+ } else { -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ -+ atomic_add(1, &mali_dmem_man->num_dmem); -+ /* for each bk_list backend, do bind */ -+ list_for_each_entry_safe(bkn, bkn_tmp , &gp->vary_todo, node) { -+ INIT_LIST_HEAD(&pages); -+ if (likely(mali_mem_defer_get_free_page_list(bkn->page_num, &pages, dmem_block))) { -+ list_del(&bkn->node); -+ mali_mem_defer_bind_allocation(bkn, &pages); -+ _mali_osk_free(bkn); -+ } else { -+ /* not enough memory will not happen */ -+ MALI_DEBUG_PRINT_ERROR(("#BIND: NOT enough memory when binded !!## \n")); -+ _mali_osk_free(gp->dmem); -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ } -+ -+ if (!list_empty(&gp->vary_todo)) { -+ MALI_DEBUG_PRINT_ERROR(("#BIND: The deferbind backend list isn't empty !!## \n")); -+ _mali_osk_free(gp->dmem); -+ return _MALI_OSK_ERR_FAULT; -+ } -+ -+ dmem->flag = MALI_DEFER_BIND_MEMORY_BINDED; -+ -+ return _MALI_OSK_ERR_OK; -+} -+ -+void mali_mem_defer_dmem_free(struct mali_gp_job *gp) -+{ -+ if (gp->dmem) { -+ atomic_dec(&mali_dmem_man->num_dmem); -+ _mali_osk_free(gp->dmem); -+ } -+} -+ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_ARM ++#include ++#endif ++#include ++ ++#include "mali_memory.h" ++#include "mali_kernel_common.h" ++#include "mali_uk_types.h" ++#include "mali_osk.h" ++#include "mali_kernel_linux.h" ++#include "mali_memory_defer_bind.h" ++#include "mali_executor.h" ++#include "mali_osk.h" ++#include "mali_scheduler.h" ++#include "mali_gp_job.h" ++ ++mali_defer_bind_manager *mali_dmem_man = NULL; ++ ++static u32 mali_dmem_get_gp_varying_size(struct mali_gp_job *gp_job) ++{ ++ return gp_job->required_varying_memsize / _MALI_OSK_MALI_PAGE_SIZE; ++} ++ ++_mali_osk_errcode_t mali_mem_defer_bind_manager_init(void) ++{ ++ mali_dmem_man = _mali_osk_calloc(1, sizeof(struct mali_defer_bind_manager)); ++ if (!mali_dmem_man) ++ return _MALI_OSK_ERR_NOMEM; ++ ++ atomic_set(&mali_dmem_man->num_used_pages, 0); ++ atomic_set(&mali_dmem_man->num_dmem, 0); ++ ++ return _MALI_OSK_ERR_OK; ++} ++ ++ ++void mali_mem_defer_bind_manager_destory(void) ++{ ++ if (mali_dmem_man) { ++ MALI_DEBUG_ASSERT(0 == atomic_read(&mali_dmem_man->num_dmem)); ++ kfree(mali_dmem_man); ++ } ++ mali_dmem_man = NULL; ++} ++ ++ ++/*allocate pages from OS memory*/ ++_mali_osk_errcode_t mali_mem_defer_alloc_mem(u32 require, struct mali_session_data *session, mali_defer_mem_block *dblock) ++{ ++ int retval = 0; ++ u32 num_pages = require; ++ mali_mem_os_mem os_mem; ++ ++ retval = mali_mem_os_alloc_pages(&os_mem, num_pages * _MALI_OSK_MALI_PAGE_SIZE); ++ ++ /* add to free pages list */ ++ if (0 == retval) { ++ MALI_DEBUG_PRINT(4, ("mali_mem_defer_alloc_mem ,,*** pages allocate = 0x%x \n", num_pages)); ++ list_splice(&os_mem.pages, &dblock->free_pages); ++ atomic_add(os_mem.count, &dblock->num_free_pages); ++ atomic_add(os_mem.count, &session->mali_mem_allocated_pages); ++ if (atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE > session->max_mali_mem_allocated_size) { ++ session->max_mali_mem_allocated_size = atomic_read(&session->mali_mem_allocated_pages) * MALI_MMU_PAGE_SIZE; ++ } ++ return _MALI_OSK_ERR_OK; ++ } else ++ return _MALI_OSK_ERR_FAULT; ++} ++ ++_mali_osk_errcode_t mali_mem_prepare_mem_for_job(struct mali_gp_job *next_gp_job, mali_defer_mem_block *dblock) ++{ ++ u32 require_page; ++ ++ if (!next_gp_job) ++ return _MALI_OSK_ERR_FAULT; ++ ++ require_page = mali_dmem_get_gp_varying_size(next_gp_job); ++ ++ MALI_DEBUG_PRINT(4, ("mali_mem_defer_prepare_mem_work, require alloc page 0x%x\n", ++ require_page)); ++ /* allocate more pages from OS */ ++ if (_MALI_OSK_ERR_OK != mali_mem_defer_alloc_mem(require_page, next_gp_job->session, dblock)) { ++ MALI_DEBUG_PRINT(1, ("ERROR##mali_mem_defer_prepare_mem_work, allocate page failed!!")); ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ ++ next_gp_job->bind_flag = MALI_DEFER_BIND_MEMORY_PREPARED; ++ ++ return _MALI_OSK_ERR_OK; ++} ++ ++ ++/* do preparetion for allocation before defer bind */ ++_mali_osk_errcode_t mali_mem_defer_bind_allocation_prepare(mali_mem_allocation *alloc, struct list_head *list, u32 *required_varying_memsize) ++{ ++ mali_mem_backend *mem_bkend = NULL; ++ struct mali_backend_bind_list *bk_list = _mali_osk_calloc(1, sizeof(struct mali_backend_bind_list)); ++ if (NULL == bk_list) ++ return _MALI_OSK_ERR_FAULT; ++ ++ INIT_LIST_HEAD(&bk_list->node); ++ /* Get backend memory */ ++ mutex_lock(&mali_idr_mutex); ++ if (!(mem_bkend = idr_find(&mali_backend_idr, alloc->backend_handle))) { ++ MALI_DEBUG_PRINT(1, ("Can't find memory backend in defer bind!\n")); ++ mutex_unlock(&mali_idr_mutex); ++ _mali_osk_free(bk_list); ++ return _MALI_OSK_ERR_FAULT; ++ } ++ mutex_unlock(&mali_idr_mutex); ++ ++ /* If the mem backend has already been bound, no need to bind again.*/ ++ if (mem_bkend->os_mem.count > 0) { ++ _mali_osk_free(bk_list); ++ return _MALI_OSK_ERR_OK; ++ } ++ ++ MALI_DEBUG_PRINT(4, ("bind_allocation_prepare:: allocation =%x vaddr=0x%x!\n", alloc, alloc->mali_vma_node.vm_node.start)); ++ ++ INIT_LIST_HEAD(&mem_bkend->os_mem.pages); ++ ++ bk_list->bkend = mem_bkend; ++ bk_list->vaddr = alloc->mali_vma_node.vm_node.start; ++ bk_list->session = alloc->session; ++ bk_list->page_num = mem_bkend->size / _MALI_OSK_MALI_PAGE_SIZE; ++ *required_varying_memsize += mem_bkend->size; ++ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_OS); ++ ++ /* add to job to do list */ ++ list_add(&bk_list->node, list); ++ ++ return _MALI_OSK_ERR_OK; ++} ++ ++ ++ ++/* bind phyiscal memory to allocation ++This function will be called in IRQ handler*/ ++static _mali_osk_errcode_t mali_mem_defer_bind_allocation(struct mali_backend_bind_list *bk_node, ++ struct list_head *pages) ++{ ++ struct mali_session_data *session = bk_node->session; ++ mali_mem_backend *mem_bkend = bk_node->bkend; ++ MALI_DEBUG_PRINT(4, ("mali_mem_defer_bind_allocation, bind bkend = %x page num=0x%x vaddr=%x session=%x\n", mem_bkend, bk_node->page_num, bk_node->vaddr, session)); ++ ++ MALI_DEBUG_ASSERT(mem_bkend->type == MALI_MEM_OS); ++ list_splice(pages, &mem_bkend->os_mem.pages); ++ mem_bkend->os_mem.count = bk_node->page_num; ++ ++ if (mem_bkend->type == MALI_MEM_OS) { ++ mali_mem_os_mali_map(&mem_bkend->os_mem, session, bk_node->vaddr, 0, ++ mem_bkend->os_mem.count, MALI_MMU_FLAGS_DEFAULT); ++ } ++ smp_wmb(); ++ bk_node->flag = MALI_DEFER_BIND_MEMORY_BINDED; ++ mem_bkend->flags &= ~MALI_MEM_BACKEND_FLAG_NOT_BINDED; ++ mem_bkend->flags |= MALI_MEM_BACKEND_FLAG_BINDED; ++ return _MALI_OSK_ERR_OK; ++} ++ ++ ++static struct list_head *mali_mem_defer_get_free_page_list(u32 count, struct list_head *pages, mali_defer_mem_block *dblock) ++{ ++ int i = 0; ++ struct mali_page_node *m_page, *m_tmp; ++ ++ if (atomic_read(&dblock->num_free_pages) < count) { ++ return NULL; ++ } else { ++ list_for_each_entry_safe(m_page, m_tmp, &dblock->free_pages, list) { ++ if (i < count) { ++ list_move_tail(&m_page->list, pages); ++ } else { ++ break; ++ } ++ i++; ++ } ++ MALI_DEBUG_ASSERT(i == count); ++ atomic_sub(count, &dblock->num_free_pages); ++ return pages; ++ } ++} ++ ++ ++/* called in job start IOCTL to bind physical memory for each allocations ++@ bk_list backend list to do defer bind ++@ pages page list to do this bind ++@ count number of pages ++*/ ++_mali_osk_errcode_t mali_mem_defer_bind(struct mali_gp_job *gp, ++ struct mali_defer_mem_block *dmem_block) ++{ ++ struct mali_defer_mem *dmem = NULL; ++ struct mali_backend_bind_list *bkn, *bkn_tmp; ++ LIST_HEAD(pages); ++ ++ if (gp->required_varying_memsize != (atomic_read(&dmem_block->num_free_pages) * _MALI_OSK_MALI_PAGE_SIZE)) { ++ MALI_DEBUG_PRINT_ERROR(("#BIND: The memsize of varying buffer not match to the pagesize of the dmem_block!!## \n")); ++ return _MALI_OSK_ERR_FAULT; ++ } ++ ++ MALI_DEBUG_PRINT(4, ("#BIND: GP job=%x## \n", gp)); ++ dmem = (mali_defer_mem *)_mali_osk_calloc(1, sizeof(struct mali_defer_mem)); ++ if (dmem) { ++ INIT_LIST_HEAD(&dmem->node); ++ gp->dmem = dmem; ++ } else { ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ ++ atomic_add(1, &mali_dmem_man->num_dmem); ++ /* for each bk_list backend, do bind */ ++ list_for_each_entry_safe(bkn, bkn_tmp , &gp->vary_todo, node) { ++ INIT_LIST_HEAD(&pages); ++ if (likely(mali_mem_defer_get_free_page_list(bkn->page_num, &pages, dmem_block))) { ++ list_del(&bkn->node); ++ mali_mem_defer_bind_allocation(bkn, &pages); ++ _mali_osk_free(bkn); ++ } else { ++ /* not enough memory will not happen */ ++ MALI_DEBUG_PRINT_ERROR(("#BIND: NOT enough memory when binded !!## \n")); ++ _mali_osk_free(gp->dmem); ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ } ++ ++ if (!list_empty(&gp->vary_todo)) { ++ MALI_DEBUG_PRINT_ERROR(("#BIND: The deferbind backend list isn't empty !!## \n")); ++ _mali_osk_free(gp->dmem); ++ return _MALI_OSK_ERR_FAULT; ++ } ++ ++ dmem->flag = MALI_DEFER_BIND_MEMORY_BINDED; ++ ++ return _MALI_OSK_ERR_OK; ++} ++ ++void mali_mem_defer_dmem_free(struct mali_gp_job *gp) ++{ ++ if (gp->dmem) { ++ atomic_dec(&mali_dmem_man->num_dmem); ++ _mali_osk_free(gp->dmem); ++ } ++} ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.h b/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.h new file mode 100644 index 000000000..defa08d52 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_defer_bind.h @@ -0,0 +1,64 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -313294,62 +313294,62 @@ index 000000000..defa08d52 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+#ifndef __MALI_MEMORY_DEFER_BIND_H_ -+#define __MALI_MEMORY_DEFER_BIND_H_ -+ -+ -+#include "mali_osk.h" -+#include "mali_session.h" -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+#include "mali_memory_types.h" -+#include "mali_memory_os_alloc.h" -+#include "mali_uk_types.h" -+ -+struct mali_gp_job; -+ -+typedef struct mali_defer_mem { -+ struct list_head node; /*dlist node in bind manager */ -+ u32 flag; -+} mali_defer_mem; -+ -+ -+typedef struct mali_defer_mem_block { -+ struct list_head free_pages; /* page pool */ -+ atomic_t num_free_pages; -+} mali_defer_mem_block; -+ -+/* varying memory list need to bind */ -+typedef struct mali_backend_bind_list { -+ struct list_head node; -+ struct mali_mem_backend *bkend; -+ u32 vaddr; -+ u32 page_num; -+ struct mali_session_data *session; -+ u32 flag; -+} mali_backend_bind_lists; -+ -+ -+typedef struct mali_defer_bind_manager { -+ atomic_t num_used_pages; -+ atomic_t num_dmem; -+} mali_defer_bind_manager; -+ -+_mali_osk_errcode_t mali_mem_defer_bind_manager_init(void); -+void mali_mem_defer_bind_manager_destory(void); -+_mali_osk_errcode_t mali_mem_defer_bind(struct mali_gp_job *gp, struct mali_defer_mem_block *dmem_block); -+_mali_osk_errcode_t mali_mem_defer_bind_allocation_prepare(mali_mem_allocation *alloc, struct list_head *list, u32 *required_varying_memsize); -+_mali_osk_errcode_t mali_mem_prepare_mem_for_job(struct mali_gp_job *next_gp_job, mali_defer_mem_block *dblock); -+void mali_mem_defer_dmem_free(struct mali_gp_job *gp); -+ -+#endif ++ */ ++#ifndef __MALI_MEMORY_DEFER_BIND_H_ ++#define __MALI_MEMORY_DEFER_BIND_H_ ++ ++ ++#include "mali_osk.h" ++#include "mali_session.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++#include "mali_memory_types.h" ++#include "mali_memory_os_alloc.h" ++#include "mali_uk_types.h" ++ ++struct mali_gp_job; ++ ++typedef struct mali_defer_mem { ++ struct list_head node; /*dlist node in bind manager */ ++ u32 flag; ++} mali_defer_mem; ++ ++ ++typedef struct mali_defer_mem_block { ++ struct list_head free_pages; /* page pool */ ++ atomic_t num_free_pages; ++} mali_defer_mem_block; ++ ++/* varying memory list need to bind */ ++typedef struct mali_backend_bind_list { ++ struct list_head node; ++ struct mali_mem_backend *bkend; ++ u32 vaddr; ++ u32 page_num; ++ struct mali_session_data *session; ++ u32 flag; ++} mali_backend_bind_lists; ++ ++ ++typedef struct mali_defer_bind_manager { ++ atomic_t num_used_pages; ++ atomic_t num_dmem; ++} mali_defer_bind_manager; ++ ++_mali_osk_errcode_t mali_mem_defer_bind_manager_init(void); ++void mali_mem_defer_bind_manager_destory(void); ++_mali_osk_errcode_t mali_mem_defer_bind(struct mali_gp_job *gp, struct mali_defer_mem_block *dmem_block); ++_mali_osk_errcode_t mali_mem_defer_bind_allocation_prepare(mali_mem_allocation *alloc, struct list_head *list, u32 *required_varying_memsize); ++_mali_osk_errcode_t mali_mem_prepare_mem_for_job(struct mali_gp_job *next_gp_job, mali_defer_mem_block *dblock); ++void mali_mem_defer_dmem_free(struct mali_gp_job *gp); ++ ++#endif diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_dma_buf.c b/drivers/gpu/arm/mali400/mali/linux/mali_memory_dma_buf.c new file mode 100644 index 000000000..1f4565127 @@ -314918,7 +314918,7 @@ index 000000000..23d8cde75 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_manager.h @@ -0,0 +1,51 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -314926,49 +314926,49 @@ index 000000000..23d8cde75 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#ifndef __MALI_MEMORY_MANAGER_H__ -+#define __MALI_MEMORY_MANAGER_H__ -+ -+#include "mali_osk.h" -+#include -+#include -+#include -+#include -+#include -+#include "mali_memory_types.h" -+#include "mali_memory_os_alloc.h" -+#include "mali_uk_types.h" -+ -+struct mali_allocation_manager { -+ rwlock_t vm_lock; -+ struct rb_root allocation_mgr_rb; -+ struct list_head head; -+ struct mutex list_mutex; -+ u32 mali_allocation_num; -+}; -+ -+extern struct idr mali_backend_idr; -+extern struct mutex mali_idr_mutex; -+ -+int mali_memory_manager_init(struct mali_allocation_manager *mgr); -+void mali_memory_manager_uninit(struct mali_allocation_manager *mgr); -+ -+void mali_mem_allocation_struct_destory(mali_mem_allocation *alloc); -+_mali_osk_errcode_t mali_mem_add_mem_size(struct mali_session_data *session, u32 mali_addr, u32 add_size); -+mali_mem_backend *mali_mem_backend_struct_search(struct mali_session_data *session, u32 mali_address); -+_mali_osk_errcode_t _mali_ukk_mem_allocate(_mali_uk_alloc_mem_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_free(_mali_uk_free_mem_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_bind(_mali_uk_bind_mem_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_unbind(_mali_uk_unbind_mem_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_cow(_mali_uk_cow_mem_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_cow_modify_range(_mali_uk_cow_modify_range_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_usage_get(_mali_uk_profiling_memory_usage_get_s *args); -+_mali_osk_errcode_t _mali_ukk_mem_resize(_mali_uk_mem_resize_s *args); -+ -+#endif -+ ++ */ ++ ++#ifndef __MALI_MEMORY_MANAGER_H__ ++#define __MALI_MEMORY_MANAGER_H__ ++ ++#include "mali_osk.h" ++#include ++#include ++#include ++#include ++#include ++#include "mali_memory_types.h" ++#include "mali_memory_os_alloc.h" ++#include "mali_uk_types.h" ++ ++struct mali_allocation_manager { ++ rwlock_t vm_lock; ++ struct rb_root allocation_mgr_rb; ++ struct list_head head; ++ struct mutex list_mutex; ++ u32 mali_allocation_num; ++}; ++ ++extern struct idr mali_backend_idr; ++extern struct mutex mali_idr_mutex; ++ ++int mali_memory_manager_init(struct mali_allocation_manager *mgr); ++void mali_memory_manager_uninit(struct mali_allocation_manager *mgr); ++ ++void mali_mem_allocation_struct_destory(mali_mem_allocation *alloc); ++_mali_osk_errcode_t mali_mem_add_mem_size(struct mali_session_data *session, u32 mali_addr, u32 add_size); ++mali_mem_backend *mali_mem_backend_struct_search(struct mali_session_data *session, u32 mali_address); ++_mali_osk_errcode_t _mali_ukk_mem_allocate(_mali_uk_alloc_mem_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_free(_mali_uk_free_mem_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_bind(_mali_uk_bind_mem_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_unbind(_mali_uk_unbind_mem_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_cow(_mali_uk_cow_mem_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_cow_modify_range(_mali_uk_cow_modify_range_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_usage_get(_mali_uk_profiling_memory_usage_get_s *args); ++_mali_osk_errcode_t _mali_ukk_mem_resize(_mali_uk_mem_resize_s *args); ++ ++#endif ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_os_alloc.c b/drivers/gpu/arm/mali400/mali/linux/mali_memory_os_alloc.c new file mode 100644 index 000000000..277534fc1 @@ -317012,7 +317012,7 @@ index 000000000..5810960e2 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_swap_alloc.h @@ -0,0 +1,121 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -317020,119 +317020,119 @@ index 000000000..5810960e2 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#ifndef __MALI_MEMORY_SWAP_ALLOC_H__ -+#define __MALI_MEMORY_SWAP_ALLOC_H__ -+ -+#include "mali_osk.h" -+#include "mali_session.h" -+ -+#include "mali_memory_types.h" -+#include "mali_pp_job.h" -+ -+/** -+ * Initialize memory swapping module. -+ */ -+_mali_osk_errcode_t mali_mem_swap_init(void); -+ -+void mali_mem_swap_term(void); -+ -+/** -+ * Return global share memory file to other modules. -+ */ -+struct file *mali_mem_swap_get_global_swap_file(void); -+ -+/** -+ * Unlock the given memory backend and pages in it could be swapped out by kernel. -+ */ -+void mali_mem_swap_unlock_single_mem_backend(mali_mem_backend *mem_bkend); -+ -+/** -+ * Remove the given memory backend from global swap list. -+ */ -+void mali_memory_swap_list_backend_delete(mali_mem_backend *mem_bkend); -+ -+/** -+ * Add the given memory backend to global swap list. -+ */ -+void mali_memory_swap_list_backend_add(mali_mem_backend *mem_bkend); -+ -+/** -+ * Allocate 1 index from bitmap used as page index in global swap file. -+ */ -+u32 mali_mem_swap_idx_alloc(void); -+ -+void mali_mem_swap_idx_free(u32 idx); -+ -+/** -+ * Allocate a new swap item without page index. -+ */ -+struct mali_swap_item *mali_mem_swap_alloc_swap_item(void); -+ -+/** -+ * Free a swap item, truncate the corresponding space in page cache and free index of page. -+ */ -+void mali_mem_swap_free_swap_item(mali_swap_item *swap_item); -+ -+/** -+ * Allocate a page node with swap item. -+ */ -+struct mali_page_node *_mali_mem_swap_page_node_allocate(void); -+ -+/** -+ * Reduce the reference count of given page node and if return 0, just free this page node. -+ */ -+_mali_osk_errcode_t _mali_mem_swap_put_page_node(struct mali_page_node *m_page); -+ -+void _mali_mem_swap_page_node_free(struct mali_page_node *m_page); -+ -+/** -+ * Free a swappable memory backend. -+ */ -+u32 mali_mem_swap_free(mali_mem_swap *swap_mem); -+ -+/** -+ * Ummap and free. -+ */ -+u32 mali_mem_swap_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped); -+ -+/** -+ * Read in a page from global swap file with the pre-allcated page index. -+ */ -+mali_bool mali_mem_swap_in_page_node(struct mali_page_node *page_node); -+ -+int mali_mem_swap_alloc_pages(mali_mem_swap *swap_mem, u32 size, u32 *bkend_idx); -+ -+_mali_osk_errcode_t mali_mem_swap_mali_map(mali_mem_swap *swap_mem, struct mali_session_data *session, u32 vaddr, u32 props); -+ -+void mali_mem_swap_mali_unmap(mali_mem_allocation *alloc); -+ -+/** -+ * When pp job created, we need swap in all of memory backend needed by this pp job. -+ */ -+int mali_mem_swap_in_pages(struct mali_pp_job *job); -+ -+/** -+ * Put all of memory backends used this pp job to the global swap list. -+ */ -+int mali_mem_swap_out_pages(struct mali_pp_job *job); -+ -+/** -+ * This will be called in page fault to process CPU read&write. -+ */ -+int mali_mem_swap_allocate_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep) ; -+ -+/** -+ * Used to process cow on demand for swappable memory backend. -+ */ -+int mali_mem_swap_cow_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep); -+ -+#ifdef MALI_MEM_SWAP_TRACKING -+void mali_mem_swap_tracking(u32 *swap_pool_size, u32 *unlock_size); -+#endif -+#endif /* __MALI_MEMORY_SWAP_ALLOC_H__ */ -+ ++ */ ++ ++#ifndef __MALI_MEMORY_SWAP_ALLOC_H__ ++#define __MALI_MEMORY_SWAP_ALLOC_H__ ++ ++#include "mali_osk.h" ++#include "mali_session.h" ++ ++#include "mali_memory_types.h" ++#include "mali_pp_job.h" ++ ++/** ++ * Initialize memory swapping module. ++ */ ++_mali_osk_errcode_t mali_mem_swap_init(void); ++ ++void mali_mem_swap_term(void); ++ ++/** ++ * Return global share memory file to other modules. ++ */ ++struct file *mali_mem_swap_get_global_swap_file(void); ++ ++/** ++ * Unlock the given memory backend and pages in it could be swapped out by kernel. ++ */ ++void mali_mem_swap_unlock_single_mem_backend(mali_mem_backend *mem_bkend); ++ ++/** ++ * Remove the given memory backend from global swap list. ++ */ ++void mali_memory_swap_list_backend_delete(mali_mem_backend *mem_bkend); ++ ++/** ++ * Add the given memory backend to global swap list. ++ */ ++void mali_memory_swap_list_backend_add(mali_mem_backend *mem_bkend); ++ ++/** ++ * Allocate 1 index from bitmap used as page index in global swap file. ++ */ ++u32 mali_mem_swap_idx_alloc(void); ++ ++void mali_mem_swap_idx_free(u32 idx); ++ ++/** ++ * Allocate a new swap item without page index. ++ */ ++struct mali_swap_item *mali_mem_swap_alloc_swap_item(void); ++ ++/** ++ * Free a swap item, truncate the corresponding space in page cache and free index of page. ++ */ ++void mali_mem_swap_free_swap_item(mali_swap_item *swap_item); ++ ++/** ++ * Allocate a page node with swap item. ++ */ ++struct mali_page_node *_mali_mem_swap_page_node_allocate(void); ++ ++/** ++ * Reduce the reference count of given page node and if return 0, just free this page node. ++ */ ++_mali_osk_errcode_t _mali_mem_swap_put_page_node(struct mali_page_node *m_page); ++ ++void _mali_mem_swap_page_node_free(struct mali_page_node *m_page); ++ ++/** ++ * Free a swappable memory backend. ++ */ ++u32 mali_mem_swap_free(mali_mem_swap *swap_mem); ++ ++/** ++ * Ummap and free. ++ */ ++u32 mali_mem_swap_release(mali_mem_backend *mem_bkend, mali_bool is_mali_mapped); ++ ++/** ++ * Read in a page from global swap file with the pre-allcated page index. ++ */ ++mali_bool mali_mem_swap_in_page_node(struct mali_page_node *page_node); ++ ++int mali_mem_swap_alloc_pages(mali_mem_swap *swap_mem, u32 size, u32 *bkend_idx); ++ ++_mali_osk_errcode_t mali_mem_swap_mali_map(mali_mem_swap *swap_mem, struct mali_session_data *session, u32 vaddr, u32 props); ++ ++void mali_mem_swap_mali_unmap(mali_mem_allocation *alloc); ++ ++/** ++ * When pp job created, we need swap in all of memory backend needed by this pp job. ++ */ ++int mali_mem_swap_in_pages(struct mali_pp_job *job); ++ ++/** ++ * Put all of memory backends used this pp job to the global swap list. ++ */ ++int mali_mem_swap_out_pages(struct mali_pp_job *job); ++ ++/** ++ * This will be called in page fault to process CPU read&write. ++ */ ++int mali_mem_swap_allocate_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep) ; ++ ++/** ++ * Used to process cow on demand for swappable memory backend. ++ */ ++int mali_mem_swap_cow_page_on_demand(mali_mem_backend *mem_bkend, u32 offset, struct page **pagep); ++ ++#ifdef MALI_MEM_SWAP_TRACKING ++void mali_mem_swap_tracking(u32 *swap_pool_size, u32 *unlock_size); ++#endif ++#endif /* __MALI_MEMORY_SWAP_ALLOC_H__ */ ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_types.h b/drivers/gpu/arm/mali400/mali/linux/mali_memory_types.h new file mode 100644 index 000000000..33db40929 @@ -317723,7 +317723,7 @@ index 000000000..33ac99509 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_util.h @@ -0,0 +1,20 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -317731,25 +317731,25 @@ index 000000000..33ac99509 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#ifndef __MALI_MEMORY_UTIL_H__ -+#define __MALI_MEMORY_UTIL_H__ -+ -+u32 mali_allocation_unref(struct mali_mem_allocation **alloc); -+ -+void mali_allocation_ref(struct mali_mem_allocation *alloc); -+ -+void mali_free_session_allocations(struct mali_session_data *session); -+ -+#endif ++ */ ++ ++#ifndef __MALI_MEMORY_UTIL_H__ ++#define __MALI_MEMORY_UTIL_H__ ++ ++u32 mali_allocation_unref(struct mali_mem_allocation **alloc); ++ ++void mali_allocation_ref(struct mali_mem_allocation *alloc); ++ ++void mali_free_session_allocations(struct mali_session_data *session); ++ ++#endif diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.c b/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.c new file mode 100644 index 000000000..0b31e3a23 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.c @@ -0,0 +1,127 @@ -+/* ++/* + * Copyright (C) 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -317757,132 +317757,132 @@ index 000000000..0b31e3a23 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "mali_osk.h" -+#include "mali_osk_mali.h" -+#include "mali_kernel_linux.h" -+#include "mali_scheduler.h" -+#include "mali_memory_os_alloc.h" -+#include "mali_memory_manager.h" -+#include "mali_memory_virtual.h" -+ -+ -+/** -+*internal helper to link node into the rb-tree -+*/ -+static inline void _mali_vma_offset_add_rb(struct mali_allocation_manager *mgr, -+ struct mali_vma_node *node) -+{ -+ struct rb_node **iter = &mgr->allocation_mgr_rb.rb_node; -+ struct rb_node *parent = NULL; -+ struct mali_vma_node *iter_node; -+ -+ while (likely(*iter)) { -+ parent = *iter; -+ iter_node = rb_entry(*iter, struct mali_vma_node, vm_rb); -+ -+ if (node->vm_node.start < iter_node->vm_node.start) -+ iter = &(*iter)->rb_left; -+ else if (node->vm_node.start > iter_node->vm_node.start) -+ iter = &(*iter)->rb_right; -+ else -+ MALI_DEBUG_ASSERT(0); -+ } -+ -+ rb_link_node(&node->vm_rb, parent, iter); -+ rb_insert_color(&node->vm_rb, &mgr->allocation_mgr_rb); -+} -+ -+/** -+ * mali_vma_offset_add() - Add offset node to RB Tree -+ */ -+int mali_vma_offset_add(struct mali_allocation_manager *mgr, -+ struct mali_vma_node *node) -+{ -+ int ret = 0; -+ write_lock(&mgr->vm_lock); -+ -+ if (node->vm_node.allocated) { -+ goto out; -+ } -+ -+ _mali_vma_offset_add_rb(mgr, node); -+ /* set to allocated */ -+ node->vm_node.allocated = 1; -+ -+out: -+ write_unlock(&mgr->vm_lock); -+ return ret; -+} -+ -+/** -+ * mali_vma_offset_remove() - Remove offset node from RB tree -+ */ -+void mali_vma_offset_remove(struct mali_allocation_manager *mgr, -+ struct mali_vma_node *node) -+{ -+ write_lock(&mgr->vm_lock); -+ -+ if (node->vm_node.allocated) { -+ rb_erase(&node->vm_rb, &mgr->allocation_mgr_rb); -+ memset(&node->vm_node, 0, sizeof(node->vm_node)); -+ } -+ write_unlock(&mgr->vm_lock); -+} -+ -+/** -+* mali_vma_offset_search - Search the node in RB tree -+*/ -+struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr, -+ unsigned long start, unsigned long pages) -+{ -+ struct mali_vma_node *node, *best; -+ struct rb_node *iter; -+ unsigned long offset; -+ read_lock(&mgr->vm_lock); -+ -+ iter = mgr->allocation_mgr_rb.rb_node; -+ best = NULL; -+ -+ while (likely(iter)) { -+ node = rb_entry(iter, struct mali_vma_node, vm_rb); -+ offset = node->vm_node.start; -+ if (start >= offset) { -+ iter = iter->rb_right; -+ best = node; -+ if (start == offset) -+ break; -+ } else { -+ iter = iter->rb_left; -+ } -+ } -+ -+ if (best) { -+ offset = best->vm_node.start + best->vm_node.size; -+ if (offset <= start + pages) -+ best = NULL; -+ } -+ read_unlock(&mgr->vm_lock); -+ -+ return best; -+} -+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mali_osk.h" ++#include "mali_osk_mali.h" ++#include "mali_kernel_linux.h" ++#include "mali_scheduler.h" ++#include "mali_memory_os_alloc.h" ++#include "mali_memory_manager.h" ++#include "mali_memory_virtual.h" ++ ++ ++/** ++*internal helper to link node into the rb-tree ++*/ ++static inline void _mali_vma_offset_add_rb(struct mali_allocation_manager *mgr, ++ struct mali_vma_node *node) ++{ ++ struct rb_node **iter = &mgr->allocation_mgr_rb.rb_node; ++ struct rb_node *parent = NULL; ++ struct mali_vma_node *iter_node; ++ ++ while (likely(*iter)) { ++ parent = *iter; ++ iter_node = rb_entry(*iter, struct mali_vma_node, vm_rb); ++ ++ if (node->vm_node.start < iter_node->vm_node.start) ++ iter = &(*iter)->rb_left; ++ else if (node->vm_node.start > iter_node->vm_node.start) ++ iter = &(*iter)->rb_right; ++ else ++ MALI_DEBUG_ASSERT(0); ++ } ++ ++ rb_link_node(&node->vm_rb, parent, iter); ++ rb_insert_color(&node->vm_rb, &mgr->allocation_mgr_rb); ++} ++ ++/** ++ * mali_vma_offset_add() - Add offset node to RB Tree ++ */ ++int mali_vma_offset_add(struct mali_allocation_manager *mgr, ++ struct mali_vma_node *node) ++{ ++ int ret = 0; ++ write_lock(&mgr->vm_lock); ++ ++ if (node->vm_node.allocated) { ++ goto out; ++ } ++ ++ _mali_vma_offset_add_rb(mgr, node); ++ /* set to allocated */ ++ node->vm_node.allocated = 1; ++ ++out: ++ write_unlock(&mgr->vm_lock); ++ return ret; ++} ++ ++/** ++ * mali_vma_offset_remove() - Remove offset node from RB tree ++ */ ++void mali_vma_offset_remove(struct mali_allocation_manager *mgr, ++ struct mali_vma_node *node) ++{ ++ write_lock(&mgr->vm_lock); ++ ++ if (node->vm_node.allocated) { ++ rb_erase(&node->vm_rb, &mgr->allocation_mgr_rb); ++ memset(&node->vm_node, 0, sizeof(node->vm_node)); ++ } ++ write_unlock(&mgr->vm_lock); ++} ++ ++/** ++* mali_vma_offset_search - Search the node in RB tree ++*/ ++struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr, ++ unsigned long start, unsigned long pages) ++{ ++ struct mali_vma_node *node, *best; ++ struct rb_node *iter; ++ unsigned long offset; ++ read_lock(&mgr->vm_lock); ++ ++ iter = mgr->allocation_mgr_rb.rb_node; ++ best = NULL; ++ ++ while (likely(iter)) { ++ node = rb_entry(iter, struct mali_vma_node, vm_rb); ++ offset = node->vm_node.start; ++ if (start >= offset) { ++ iter = iter->rb_right; ++ best = node; ++ if (start == offset) ++ break; ++ } else { ++ iter = iter->rb_left; ++ } ++ } ++ ++ if (best) { ++ offset = best->vm_node.start + best->vm_node.size; ++ if (offset <= start + pages) ++ best = NULL; ++ } ++ read_unlock(&mgr->vm_lock); ++ ++ return best; ++} ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.h b/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.h new file mode 100644 index 000000000..fd03ed9f2 --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_memory_virtual.h @@ -0,0 +1,35 @@ -+/* ++/* + * Copyright (C) 2013-2014, 2016-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -317890,33 +317890,33 @@ index 000000000..fd03ed9f2 + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+#ifndef __MALI_GPU_VMEM_H__ -+#define __MALI_GPU_VMEM_H__ -+ -+#include "mali_osk.h" -+#include "mali_session.h" -+#include -+#include -+#include -+#include -+#include -+#include "mali_memory_types.h" -+#include "mali_memory_os_alloc.h" -+#include "mali_memory_manager.h" -+ -+ -+ -+int mali_vma_offset_add(struct mali_allocation_manager *mgr, -+ struct mali_vma_node *node); -+ -+void mali_vma_offset_remove(struct mali_allocation_manager *mgr, -+ struct mali_vma_node *node); -+ -+struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr, -+ unsigned long start, unsigned long pages); -+ -+#endif ++ */ ++#ifndef __MALI_GPU_VMEM_H__ ++#define __MALI_GPU_VMEM_H__ ++ ++#include "mali_osk.h" ++#include "mali_session.h" ++#include ++#include ++#include ++#include ++#include ++#include "mali_memory_types.h" ++#include "mali_memory_os_alloc.h" ++#include "mali_memory_manager.h" ++ ++ ++ ++int mali_vma_offset_add(struct mali_allocation_manager *mgr, ++ struct mali_vma_node *node); ++ ++void mali_vma_offset_remove(struct mali_allocation_manager *mgr, ++ struct mali_vma_node *node); ++ ++struct mali_vma_node *mali_vma_offset_search(struct mali_allocation_manager *mgr, ++ unsigned long start, unsigned long pages); ++ ++#endif diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_atomics.c new file mode 100644 index 000000000..5bc0e52eb @@ -317988,7 +317988,7 @@ index 000000000..fb9ccd2ad --- /dev/null +++ b/drivers/gpu/arm/mali400/mali/linux/mali_osk_bitmap.c @@ -0,0 +1,152 @@ -+/* ++/* + * Copyright (C) 2010, 2013-2017 ARM Limited. All rights reserved. + * + * This program is free software and is provided to you under the terms of the GNU General Public License version 2 @@ -317996,150 +317996,150 @@ index 000000000..fb9ccd2ad + * + * A copy of the licence is included with the program, and can also be obtained from Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -+ */ -+ -+/** -+ * @file mali_osk_bitmap.c -+ * Implementation of the OS abstraction layer for the kernel device driver -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "common/mali_kernel_common.h" -+#include "mali_osk_types.h" -+#include "mali_osk.h" -+ -+u32 _mali_osk_bitmap_alloc(struct _mali_osk_bitmap *bitmap) -+{ -+ u32 obj; -+ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ _mali_osk_spinlock_lock(bitmap->lock); -+ -+ obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->reserve); -+ -+ if (obj < bitmap->max) { -+ set_bit(obj, bitmap->table); -+ } else { -+ obj = -1; -+ } -+ -+ if (obj != -1) -+ --bitmap->avail; -+ _mali_osk_spinlock_unlock(bitmap->lock); -+ -+ return obj; -+} -+ -+void _mali_osk_bitmap_free(struct _mali_osk_bitmap *bitmap, u32 obj) -+{ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ _mali_osk_bitmap_free_range(bitmap, obj, 1); -+} -+ -+u32 _mali_osk_bitmap_alloc_range(struct _mali_osk_bitmap *bitmap, int cnt) -+{ -+ u32 obj; -+ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ if (0 >= cnt) { -+ return -1; -+ } -+ -+ if (1 == cnt) { -+ return _mali_osk_bitmap_alloc(bitmap); -+ } -+ -+ _mali_osk_spinlock_lock(bitmap->lock); -+ obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, -+ bitmap->last, cnt, 0); -+ -+ if (obj >= bitmap->max) { -+ obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, -+ bitmap->reserve, cnt, 0); -+ } -+ -+ if (obj < bitmap->max) { -+ bitmap_set(bitmap->table, obj, cnt); -+ -+ bitmap->last = (obj + cnt); -+ if (bitmap->last >= bitmap->max) { -+ bitmap->last = bitmap->reserve; -+ } -+ } else { -+ obj = -1; -+ } -+ -+ if (obj != -1) { -+ bitmap->avail -= cnt; -+ } -+ -+ _mali_osk_spinlock_unlock(bitmap->lock); -+ -+ return obj; -+} -+ -+u32 _mali_osk_bitmap_avail(struct _mali_osk_bitmap *bitmap) -+{ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ return bitmap->avail; -+} -+ -+void _mali_osk_bitmap_free_range(struct _mali_osk_bitmap *bitmap, u32 obj, int cnt) -+{ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ _mali_osk_spinlock_lock(bitmap->lock); -+ bitmap_clear(bitmap->table, obj, cnt); -+ bitmap->last = min(bitmap->last, obj); -+ -+ bitmap->avail += cnt; -+ _mali_osk_spinlock_unlock(bitmap->lock); -+} -+ -+int _mali_osk_bitmap_init(struct _mali_osk_bitmap *bitmap, u32 num, u32 reserve) -+{ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ MALI_DEBUG_ASSERT(reserve <= num); -+ -+ bitmap->reserve = reserve; -+ bitmap->last = reserve; -+ bitmap->max = num; -+ bitmap->avail = num - reserve; -+ bitmap->lock = _mali_osk_spinlock_init(_MALI_OSK_LOCKFLAG_UNORDERED, _MALI_OSK_LOCK_ORDER_FIRST); -+ if (!bitmap->lock) { -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) * -+ sizeof(long), GFP_KERNEL); -+ if (!bitmap->table) { -+ _mali_osk_spinlock_term(bitmap->lock); -+ return _MALI_OSK_ERR_NOMEM; -+ } -+ -+ return _MALI_OSK_ERR_OK; -+} -+ -+void _mali_osk_bitmap_term(struct _mali_osk_bitmap *bitmap) -+{ -+ MALI_DEBUG_ASSERT_POINTER(bitmap); -+ -+ if (NULL != bitmap->lock) { -+ _mali_osk_spinlock_term(bitmap->lock); -+ } -+ -+ if (NULL != bitmap->table) { -+ kfree(bitmap->table); -+ } -+} -+ ++ */ ++ ++/** ++ * @file mali_osk_bitmap.c ++ * Implementation of the OS abstraction layer for the kernel device driver ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include "common/mali_kernel_common.h" ++#include "mali_osk_types.h" ++#include "mali_osk.h" ++ ++u32 _mali_osk_bitmap_alloc(struct _mali_osk_bitmap *bitmap) ++{ ++ u32 obj; ++ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ _mali_osk_spinlock_lock(bitmap->lock); ++ ++ obj = find_next_zero_bit(bitmap->table, bitmap->max, bitmap->reserve); ++ ++ if (obj < bitmap->max) { ++ set_bit(obj, bitmap->table); ++ } else { ++ obj = -1; ++ } ++ ++ if (obj != -1) ++ --bitmap->avail; ++ _mali_osk_spinlock_unlock(bitmap->lock); ++ ++ return obj; ++} ++ ++void _mali_osk_bitmap_free(struct _mali_osk_bitmap *bitmap, u32 obj) ++{ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ _mali_osk_bitmap_free_range(bitmap, obj, 1); ++} ++ ++u32 _mali_osk_bitmap_alloc_range(struct _mali_osk_bitmap *bitmap, int cnt) ++{ ++ u32 obj; ++ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ if (0 >= cnt) { ++ return -1; ++ } ++ ++ if (1 == cnt) { ++ return _mali_osk_bitmap_alloc(bitmap); ++ } ++ ++ _mali_osk_spinlock_lock(bitmap->lock); ++ obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, ++ bitmap->last, cnt, 0); ++ ++ if (obj >= bitmap->max) { ++ obj = bitmap_find_next_zero_area(bitmap->table, bitmap->max, ++ bitmap->reserve, cnt, 0); ++ } ++ ++ if (obj < bitmap->max) { ++ bitmap_set(bitmap->table, obj, cnt); ++ ++ bitmap->last = (obj + cnt); ++ if (bitmap->last >= bitmap->max) { ++ bitmap->last = bitmap->reserve; ++ } ++ } else { ++ obj = -1; ++ } ++ ++ if (obj != -1) { ++ bitmap->avail -= cnt; ++ } ++ ++ _mali_osk_spinlock_unlock(bitmap->lock); ++ ++ return obj; ++} ++ ++u32 _mali_osk_bitmap_avail(struct _mali_osk_bitmap *bitmap) ++{ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ return bitmap->avail; ++} ++ ++void _mali_osk_bitmap_free_range(struct _mali_osk_bitmap *bitmap, u32 obj, int cnt) ++{ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ _mali_osk_spinlock_lock(bitmap->lock); ++ bitmap_clear(bitmap->table, obj, cnt); ++ bitmap->last = min(bitmap->last, obj); ++ ++ bitmap->avail += cnt; ++ _mali_osk_spinlock_unlock(bitmap->lock); ++} ++ ++int _mali_osk_bitmap_init(struct _mali_osk_bitmap *bitmap, u32 num, u32 reserve) ++{ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ MALI_DEBUG_ASSERT(reserve <= num); ++ ++ bitmap->reserve = reserve; ++ bitmap->last = reserve; ++ bitmap->max = num; ++ bitmap->avail = num - reserve; ++ bitmap->lock = _mali_osk_spinlock_init(_MALI_OSK_LOCKFLAG_UNORDERED, _MALI_OSK_LOCK_ORDER_FIRST); ++ if (!bitmap->lock) { ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ bitmap->table = kzalloc(BITS_TO_LONGS(bitmap->max) * ++ sizeof(long), GFP_KERNEL); ++ if (!bitmap->table) { ++ _mali_osk_spinlock_term(bitmap->lock); ++ return _MALI_OSK_ERR_NOMEM; ++ } ++ ++ return _MALI_OSK_ERR_OK; ++} ++ ++void _mali_osk_bitmap_term(struct _mali_osk_bitmap *bitmap) ++{ ++ MALI_DEBUG_ASSERT_POINTER(bitmap); ++ ++ if (NULL != bitmap->lock) { ++ _mali_osk_spinlock_term(bitmap->lock); ++ } ++ ++ if (NULL != bitmap->table) { ++ kfree(bitmap->table); ++ } ++} ++ diff --git a/drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c b/drivers/gpu/arm/mali400/mali/linux/mali_osk_irq.c new file mode 100644 index 000000000..5c8b9ceab @@ -911500,52 +911500,52 @@ index 000000000..0abd524a6 +++ b/drivers/mtd/rknand/Kconfig @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: GPL-2.0 -+# -+# linux/drivers/mtd/rknand/Kconfig -+# -+ -+config MTD_RKNAND -+ tristate "RK NAND Device Support" -+ depends on MTD -+ select MTD_RK_NAND_IDS -+ help -+ RK NAND Device Support -+if MTD_RKNAND -+ -+config MTD_NAND_RK29XX -+ tristate "RK on-chip NAND Flash Controller driver with FTL" -+ depends on MTD_RKNAND -+ default y -+ help -+ This enables the RK28xx on-chip NAND flash controller and NFTL driver. -+ -+config MTD_RKNAND_BUFFER -+ tristate "RK Nand buffer write enables" -+ depends on MTD_RKNAND -+ default y -+ help -+ -+config MTD_EMMC_CLK_POWER_SAVE -+ tristate "RK emmc clock power save" -+ depends on MTD_RKNAND -+ default n -+ help -+ -+config MTD_NAND_RK29XX_DEBUG -+ tristate "RK Nand driver debug enables" -+ depends on MTD_RKNAND -+ default n -+ help -+ -+config MTD_NAND_RK29XX_DEBUG_VERBOSE -+ int "Debugging verbosity (0 = quiet, 3 = noisy)" -+ depends on MTD_NAND_RK29XX_DEBUG -+ default "0" -+ help -+ Determines the verbosity level of the MTD NAND debugging messages. -+ -+endif # MTD_RKNAND -+ ++# ++# linux/drivers/mtd/rknand/Kconfig ++# ++ ++config MTD_RKNAND ++ tristate "RK NAND Device Support" ++ depends on MTD ++ select MTD_RK_NAND_IDS ++ help ++ RK NAND Device Support ++if MTD_RKNAND ++ ++config MTD_NAND_RK29XX ++ tristate "RK on-chip NAND Flash Controller driver with FTL" ++ depends on MTD_RKNAND ++ default y ++ help ++ This enables the RK28xx on-chip NAND flash controller and NFTL driver. ++ ++config MTD_RKNAND_BUFFER ++ tristate "RK Nand buffer write enables" ++ depends on MTD_RKNAND ++ default y ++ help ++ ++config MTD_EMMC_CLK_POWER_SAVE ++ tristate "RK emmc clock power save" ++ depends on MTD_RKNAND ++ default n ++ help ++ ++config MTD_NAND_RK29XX_DEBUG ++ tristate "RK Nand driver debug enables" ++ depends on MTD_RKNAND ++ default n ++ help ++ ++config MTD_NAND_RK29XX_DEBUG_VERBOSE ++ int "Debugging verbosity (0 = quiet, 3 = noisy)" ++ depends on MTD_NAND_RK29XX_DEBUG ++ default "0" ++ help ++ Determines the verbosity level of the MTD NAND debugging messages. ++ ++endif # MTD_RKNAND ++ diff --git a/drivers/mtd/rknand/Makefile b/drivers/mtd/rknand/Makefile new file mode 100644 index 000000000..5ddcdf1a7 @@ -911553,14 +911553,14 @@ index 000000000..5ddcdf1a7 +++ b/drivers/mtd/rknand/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 -+# -+# linux/drivers/rknand/Makefile -+# -+# $Id: Makefile,v 1.3 2011/01/21 10:12:56 Administrator Exp $ -+# -+obj-$(CONFIG_MTD_NAND_RK29XX) += rknand_base_ko.o -+ -+ ++# ++# linux/drivers/rknand/Makefile ++# ++# $Id: Makefile,v 1.3 2011/01/21 10:12:56 Administrator Exp $ ++# ++obj-$(CONFIG_MTD_NAND_RK29XX) += rknand_base_ko.o ++ ++ diff --git a/drivers/mtd/rknand/api_flash.h b/drivers/mtd/rknand/api_flash.h new file mode 100644 index 000000000..e97ee3d5a @@ -911568,208 +911568,208 @@ index 000000000..e97ee3d5a +++ b/drivers/mtd/rknand/api_flash.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+/******************************************************************************** -+********************************************************************************* -+ COPYRIGHT (c) 2004 BY ROCK-CHIP FUZHOU -+ -- ALL RIGHTS RESERVED -- -+ -+File Name: api_flash.h -+Author: XUESHAN LIN -+Created: 1st Dec 2008 -+Modified: -+Revision: 1.00 -+Modify log: -+ 1.01 ????FtlClose?Ó¿Úº??? 2009.10.15 lxs -+******************************************************************************** -+********************************************************************************/ -+#ifndef _API_FLASH_H -+#define _API_FLASH_H -+ -+//1????Ô­?????? -+/*************************************************************************** -+????????:FTL??FLASH??ʼ?? -+???Ú²???:?? -+???Ú²???: -+ 0=?ý³£·µ»? -+ 1=Ó³????????, ??Ç¿?Ƶ͸? -+ 2=flash??ʼ??ʧ??,??????Ó²????????Òª???й̼????? -+ ????Öµ:?Ú²?????, ???ý¶¯²»¿?ʹ?? -+˵ ??:?ϵ?Ö»??????Ò»?γ?ʼ?????? -+***************************************************************************/ -+extern int FtlInit(unsigned int nandcBaseAddr,unsigned char pageRemapEn); -+extern int FTLInit_WithoutPageRemap(void); -+extern int FTLInit(void); -+ -+ -+/*************************************************************************** -+????????:??È¡FLASH??????Á¿ -+???Ú²???: -+ DISK_NAND_CODE:?̼??? -+ DISK_NAND_DATA:ϵͳ?????? -+ DISK_NAND_USER:?û??? -+???Ú²???:???????????? -+˵ ??: -+***************************************************************************/ -+extern unsigned int FtlGetCapacity(unsigned char LUN); -+ -+/*************************************************************************** -+????????:???????Ó¿? -+???Ú²???:LUN=?ß¼???????, Index=??ʼ??????Ö·, buf=???Ý»?????, nSec=?????? -+???Ú²???:0=??È¡??È·; ??0=??È¡????, ???ݲ????? -+???ú???: -+˵ ??: -+***************************************************************************/ -+extern int FtlRead(unsigned char LUN, unsigned int Index, unsigned int nSec, void *buf); -+ -+/*************************************************************************** -+????????:д?????Ó¿? -+???Ú²???:LUN=?ß¼???????, Index=??ʼ??????Ö·, buf=???Ý»?????, nSec=?????? -+???Ú²???:0=??ȷд??; ??0=д????ʧ??, ????û?б???ȷд?? -+???ú???: -+˵ ??: -+***************************************************************************/ -+extern int FtlWrite(unsigned char LUN, unsigned int Index, unsigned int nSec, void *buf); -+ -+/*************************************************************************** -+????????:MLC FLASH????Ë¢?? -+???Ú²???: -+???Ú²???: -+???ú???: -+˵ ??:??ϵͳIDLE/?ڱȽϼ??ж?????ʱ(??A-B???Å¡?Ƶ??????Ô´??)???øú???, -+ ?ܼ?ʱ??????Ƶ?????жÁ»???????,????Ö´??ʱ?????ܽϳ?(????ms???Á¼?s) -+***************************************************************************/ -+extern void FlashRefreshHook(void); -+ -+/*************************************************************************** -+????????:AHB??Ƶ????ʱ??Òª???ô˽ӿ?À´????FLASHʱ?? -+???Ú²???:AHBnKHz=??Ƶ(AHB) -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FlashTimingCfg(unsigned int AHBnKHz); -+ -+/*************************************************************************** -+????????:FTL ?رգ??Ø»?ʱ???? -+???Ú²???:?? -+???Ú²???:?? -+˵ ??:?Ø»?ʱ????????д?ļ??????????????? -+***************************************************************************/ -+extern void FtlClose(void); -+ -+/*************************************************************************** -+????????:FTL ??ʱ?ص???????ϵͳ1S???Òµ???Ò»?? -+???Ú²???:?? -+???Ú²???:?? -+˵ ??:FTL??һЩCACHE?Ú¶?ʱ?л?дflash -+***************************************************************************/ -+extern void FtlTimeHook(void); -+ -+/*************************************************************************** -+????????:??È¡ flash page ??С???Ô±????濪????, -+???Ú²???:?? -+???Ú²???:page??С??sector??λ -+???ú???: -+˵??: ??Òª??FTLInit???Å¿??? -+***************************************************************************/ -+extern int FlashGetPageSize(void); -+ -+/*************************************************************************** -+????????:AHB??Ƶ????ʱ??Òª???ô˽ӿ?À´????FLASHʱ?? -+???Ú²???:AHBnMHz=??Ƶ(AHB) -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FlashTimingCfg(unsigned int AHBnKHz); -+ -+/*************************************************************************** -+????????:ϵͳ??д?????? -+???Ú²???: -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FtlFlashSysProtSetOn(void); -+ -+/*************************************************************************** -+????????:ϵͳ??д???? -+???Ú²???: -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FtlFlashSysProtSetOff(void); -+ -+/*************************************************************************** -+????????:?Á³?ϵͳ?Ì£?????ʱʹ?? -+???Ú²???: -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FtlLowFormatSysDisk(void); -+ -+extern int FtlWriteImage(unsigned int Index, unsigned int nSec, void *buf); -+/*************************************************************************** -+????????:?????л?????cache д??cache ?? -+???Ú²???: -+???Ú²???: -+???ú???: -+***************************************************************************/ -+extern void FtlCacheDelayWriteALL(void); -+ -+/*************************************************************************** -+????????:???ô???д??????Ö·?? -+???Ú²???:LBA??Ö·??С??LBA?ĵ?ַд???? -+???Ú²???: -+???ú???: -+***************************************************************************/ -+void FtlSetSysProtAddr(int LBA); -+ -+ -+/*************************************************************************** -+????????:??È¡FLASH??????Á¿ -+???Ú²???:?Ì·? -+???Ú²???:??Á¿,??????Ϊ??λ -+???ú???: -+***************************************************************************/ -+int FtlGetPageZoneCapacity(void); -+ -+/*************************************************************************** -+????????:?Á¶????? -+???Ú²???:Index=??????, nSec=?????? -+???Ú²???:?Áµ????????Ú»?????buf?? -+???ú???: -+***************************************************************************/ -+int FtlPageWrite(int Index, int nSec, void *buf); -+ -+ -+/*************************************************************************** -+????????:?Á¶????? -+???Ú²???:Index=??????, nSec=?????? -+???Ú²???:?Áµ????????Ú»?????buf?? -+???ú???: -+***************************************************************************/ -+int FtlPageRead(int Index, int nSec, void *buf); -+ -+ -+/*************************************************************************** -+????????:??È¡ SN sector??Ï¢ -+???Ú²???:pbuf -+???Ú²???: -+???ú???: -+×¢????Ï¢????Òª??flash ???????غ????ܵ??ã?pbuf??С??Òª???Úµ???512 bytes????????ϢΪ512 -+ bytes?? -+***************************************************************************/ -+char GetSNSectorInfo(char * pbuf); -+ -+ -+extern int NandInit(void); -+extern int NandRead(unsigned int Index, unsigned int nSec, void * buf) ; -+extern int NandWriteImage(unsigned int Index, unsigned int nSec, void * buf); -+extern int NandWrite(unsigned int Index, unsigned int nSec, void * buf) ; -+extern int NandDeInit(void) ; -+extern int NandForceDeInit(void); -+extern unsigned int NandGetCapacity(void); -+extern void NandSetSysProtAddr(unsigned int SysImageWriteEndAdd); -+extern void FtlDelayWriteCacheEn(unsigned int en); -+#endif ++/******************************************************************************** ++********************************************************************************* ++ COPYRIGHT (c) 2004 BY ROCK-CHIP FUZHOU ++ -- ALL RIGHTS RESERVED -- ++ ++File Name: api_flash.h ++Author: XUESHAN LIN ++Created: 1st Dec 2008 ++Modified: ++Revision: 1.00 ++Modify log: ++ 1.01 ????FtlClose?Ó¿Úº??? 2009.10.15 lxs ++******************************************************************************** ++********************************************************************************/ ++#ifndef _API_FLASH_H ++#define _API_FLASH_H ++ ++//1????Ô­?????? ++/*************************************************************************** ++????????:FTL??FLASH??ʼ?? ++???Ú²???:?? ++???Ú²???: ++ 0=?������? ++ 1=Ó³????????, ??Ç¿?Ƶ͸? ++ 2=flash??ʼ??ʧ??,??????Ó²????????Òª???й̼????? ++ ????Öµ:?Ú²?????, ???������?ʹ?? ++˵ ??:?ϵ?Ö»??????Ò»?γ?ʼ?????? ++***************************************************************************/ ++extern int FtlInit(unsigned int nandcBaseAddr,unsigned char pageRemapEn); ++extern int FTLInit_WithoutPageRemap(void); ++extern int FTLInit(void); ++ ++ ++/*************************************************************************** ++????????:??È¡FLASH??????�� ++???Ú²???: ++ DISK_NAND_CODE:?̼??? ++ DISK_NAND_DATA:ϵͳ?????? ++ DISK_NAND_USER:?û??? ++???Ú²???:???????????? ++˵ ??: ++***************************************************************************/ ++extern unsigned int FtlGetCapacity(unsigned char LUN); ++ ++/*************************************************************************** ++????????:???????Ó¿? ++???Ú²???:LUN=?ß¼???????, Index=??ʼ??????Ö·, buf=???Ý»?????, nSec=?????? ++???Ú²???:0=??È¡??È·; ??0=??È¡????, ???ݲ????? ++???ú???: ++˵ ??: ++***************************************************************************/ ++extern int FtlRead(unsigned char LUN, unsigned int Index, unsigned int nSec, void *buf); ++ ++/*************************************************************************** ++????????:д?????Ó¿? ++???Ú²???:LUN=?ß¼???????, Index=??ʼ??????Ö·, buf=???Ý»?????, nSec=?????? ++???Ú²???:0=??ȷд??; ??0=д????ʧ??, ????û?б???ȷд?? ++???ú???: ++˵ ??: ++***************************************************************************/ ++extern int FtlWrite(unsigned char LUN, unsigned int Index, unsigned int nSec, void *buf); ++ ++/*************************************************************************** ++????????:MLC FLASH????Ë¢?? ++???Ú²???: ++???Ú²???: ++???ú???: ++˵ ??:??ϵͳIDLE/?ڱȽϼ??ж?????ʱ(??A-B???Å¡?Ƶ??????Ô´??)???øú???, ++ ?ܼ?ʱ??????Ƶ?????�???????,????Ö´??ʱ?????ܽϳ?(????ms???��?s) ++***************************************************************************/ ++extern void FlashRefreshHook(void); ++ ++/*************************************************************************** ++????????:AHB??Ƶ????ʱ??Òª???ô˽ӿ?��????FLASHʱ?? ++???Ú²???:AHBnKHz=??Ƶ(AHB) ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FlashTimingCfg(unsigned int AHBnKHz); ++ ++/*************************************************************************** ++????????:FTL ?رգ??Ø»?ʱ???? ++???Ú²???:?? ++???Ú²???:?? ++˵ ??:?Ø»?ʱ????????д?ļ??????????????? ++***************************************************************************/ ++extern void FtlClose(void); ++ ++/*************************************************************************** ++????????:FTL ??ʱ?ص???????ϵͳ1S???Òµ???Ò»?? ++???Ú²???:?? ++???Ú²???:?? ++˵ ??:FTL??һЩCACHE?Ú¶?ʱ?л?дflash ++***************************************************************************/ ++extern void FtlTimeHook(void); ++ ++/*************************************************************************** ++????????:??È¡ flash page ??С???Ô±????濪????, ++???Ú²???:?? ++???Ú²???:page??С??sector??λ ++???ú???: ++˵??: ??Òª??FTLInit???Å¿??? ++***************************************************************************/ ++extern int FlashGetPageSize(void); ++ ++/*************************************************************************** ++????????:AHB??Ƶ????ʱ??Òª???ô˽ӿ?��????FLASHʱ?? ++???Ú²???:AHBnMHz=??Ƶ(AHB) ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FlashTimingCfg(unsigned int AHBnKHz); ++ ++/*************************************************************************** ++????????:ϵͳ??д?????? ++???Ú²???: ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FtlFlashSysProtSetOn(void); ++ ++/*************************************************************************** ++????????:ϵͳ??д???? ++???Ú²???: ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FtlFlashSysProtSetOff(void); ++ ++/*************************************************************************** ++????????:?��?ϵͳ?Ì£?????ʱʹ?? ++???Ú²???: ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FtlLowFormatSysDisk(void); ++ ++extern int FtlWriteImage(unsigned int Index, unsigned int nSec, void *buf); ++/*************************************************************************** ++????????:?????л?????cache д??cache ?? ++???Ú²???: ++???Ú²???: ++???ú???: ++***************************************************************************/ ++extern void FtlCacheDelayWriteALL(void); ++ ++/*************************************************************************** ++????????:???ô???д??????Ö·?? ++???Ú²???:LBA??Ö·??С??LBA?ĵ?ַд???? ++???Ú²???: ++???ú???: ++***************************************************************************/ ++void FtlSetSysProtAddr(int LBA); ++ ++ ++/*************************************************************************** ++????????:??È¡FLASH??????�� ++???Ú²???:?Ì·? ++???Ú²???:??��,??????Ϊ??λ ++???ú???: ++***************************************************************************/ ++int FtlGetPageZoneCapacity(void); ++ ++/*************************************************************************** ++????????:?��????? ++???Ú²???:Index=??????, nSec=?????? ++???Ú²???:?��????????Ú»?????buf?? ++???ú???: ++***************************************************************************/ ++int FtlPageWrite(int Index, int nSec, void *buf); ++ ++ ++/*************************************************************************** ++????????:?��????? ++???Ú²???:Index=??????, nSec=?????? ++???Ú²???:?��????????Ú»?????buf?? ++???ú???: ++***************************************************************************/ ++int FtlPageRead(int Index, int nSec, void *buf); ++ ++ ++/*************************************************************************** ++????????:??È¡ SN sector??Ï¢ ++???Ú²???:pbuf ++???Ú²???: ++???ú???: ++×¢????Ï¢????Òª??flash ???????غ????ܵ??ã?pbuf??С??Òª???Úµ???512 bytes????????ϢΪ512 ++ bytes?? ++***************************************************************************/ ++char GetSNSectorInfo(char * pbuf); ++ ++ ++extern int NandInit(void); ++extern int NandRead(unsigned int Index, unsigned int nSec, void * buf) ; ++extern int NandWriteImage(unsigned int Index, unsigned int nSec, void * buf); ++extern int NandWrite(unsigned int Index, unsigned int nSec, void * buf) ; ++extern int NandDeInit(void) ; ++extern int NandForceDeInit(void); ++extern unsigned int NandGetCapacity(void); ++extern void NandSetSysProtAddr(unsigned int SysImageWriteEndAdd); ++extern void FtlDelayWriteCacheEn(unsigned int en); ++#endif diff --git a/drivers/mtd/rknand/rknand_base.h b/drivers/mtd/rknand/rknand_base.h new file mode 100644 index 000000000..e04eb09df @@ -911777,98 +911777,98 @@ index 000000000..e04eb09df +++ b/drivers/mtd/rknand/rknand_base.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * linux/drivers/mtd/rknand/rknand_base.c -+ * -+ * Copyright (C) 2005-2009 Fuzhou Rockchip Electronics -+ * ZYF -+ * -+ * -+ */ -+#ifndef _RKNAND_BASE_H -+#define _RKNAND_BASE_H -+//#include "api_flash.h" -+ -+#define DRIVER_NAME "rk29xxnand" -+ -+#define NAND_DEBUG_LEVEL0 0 -+#define NAND_DEBUG_LEVEL1 1 -+#define NAND_DEBUG_LEVEL2 2 -+#define NAND_DEBUG_LEVEL3 3 -+//#define PAGE_REMAP -+ -+#ifndef CONFIG_RKFTL_PAGECACHE_SIZE -+#define CONFIG_RKFTL_PAGECACHE_SIZE 64 //????pageÓ³??????С????λΪMB,mount ??/data/data?¡? -+#endif -+ -+extern unsigned long SysImageWriteEndAdd; -+extern int g_num_partitions; -+ -+/* -+ * rknand_state_t - chip states -+ * Enumeration for Rknand flash chip state -+ */ -+typedef enum { -+ FL_READY, -+ FL_READING, -+ FL_WRITING, -+ FL_ERASING, -+ FL_SYNCING, -+ FL_UNVALID, -+} rknand_state_t; -+ -+struct rknand_chip { -+ wait_queue_head_t wq; -+ rknand_state_t state; -+ int rknand_schedule_enable;//1 enable ,0 disable -+ void (*pFlashCallBack)(void);//call back funtion -+}; -+ -+struct rknand_info { -+ int enable; -+ char *pbuf; -+ int bufSize; -+ unsigned int SysImageWriteEndAdd; -+ unsigned int nandCapacity; -+ struct rknand_chip rknand; -+ int (*ftl_cache_en)(int en); -+ int (*ftl_read) (int Index, int nSec, void *buf); -+ int (*ftl_write) (int Index, int nSec, void *buf ,int mode); -+ int (*ftl_write_panic) (int Index, int nSec, void *buf); -+ int (*ftl_close)(void); -+ int (*ftl_sync)(void); -+ int (*proc_bufread)(char *page); -+ int (*proc_ftlread)(char *page); -+ int (*rknand_schedule_enable)(int en); -+ int (*add_rknand_device)(struct rknand_info * prknand_Info); -+ int (*get_rknand_device)(struct rknand_info ** prknand_Info); -+ void (*rknand_buffer_shutdown)(void); -+ int (*GetIdBlockSysData)(char * buf, int Sector); -+ char (*GetSNSectorInfo)(char * pbuf); -+ char (*GetChipSectorInfo)(char * pbuf); -+ int emmc_clk_power_save_en; -+ char *pdmaBuf; -+ void (*nand_timing_config)(unsigned long AHBnKHz); -+ void (*rknand_suspend)(void); -+ void (*rknand_resume)(void); -+ int (*rknand_re_init)(void); -+ void (*rknand_dev_cache_flush)(void); -+ int (*ftl_discard) (int Index, int nSec); -+ int reserved[20]; -+}; -+ -+extern int rknand_queue_read(int Index, int nSec, void *buf); -+extern int rknand_queue_write(int Index, int nSec, void *buf,int mode); -+extern int rknand_buffer_init(char * pbuf,int size); -+extern void rknand_buffer_data_init(void); -+extern void rknand_buffer_shutdown(void); -+extern int add_rknand_device(struct rknand_info * prknand_Info); -+extern int get_rknand_device(struct rknand_info ** prknand_Info); -+extern int rknand_buffer_sync(void); -+extern void rknand_cache_flush(void); -+extern void rknand_dev_cache_flush(void); -+ -+#endif ++/* ++ * linux/drivers/mtd/rknand/rknand_base.c ++ * ++ * Copyright (C) 2005-2009 Fuzhou Rockchip Electronics ++ * ZYF ++ * ++ * ++ */ ++#ifndef _RKNAND_BASE_H ++#define _RKNAND_BASE_H ++//#include "api_flash.h" ++ ++#define DRIVER_NAME "rk29xxnand" ++ ++#define NAND_DEBUG_LEVEL0 0 ++#define NAND_DEBUG_LEVEL1 1 ++#define NAND_DEBUG_LEVEL2 2 ++#define NAND_DEBUG_LEVEL3 3 ++//#define PAGE_REMAP ++ ++#ifndef CONFIG_RKFTL_PAGECACHE_SIZE ++#define CONFIG_RKFTL_PAGECACHE_SIZE 64 //????pageÓ³??????С????λΪMB,mount ??/data/data?¡? ++#endif ++ ++extern unsigned long SysImageWriteEndAdd; ++extern int g_num_partitions; ++ ++/* ++ * rknand_state_t - chip states ++ * Enumeration for Rknand flash chip state ++ */ ++typedef enum { ++ FL_READY, ++ FL_READING, ++ FL_WRITING, ++ FL_ERASING, ++ FL_SYNCING, ++ FL_UNVALID, ++} rknand_state_t; ++ ++struct rknand_chip { ++ wait_queue_head_t wq; ++ rknand_state_t state; ++ int rknand_schedule_enable;//1 enable ,0 disable ++ void (*pFlashCallBack)(void);//call back funtion ++}; ++ ++struct rknand_info { ++ int enable; ++ char *pbuf; ++ int bufSize; ++ unsigned int SysImageWriteEndAdd; ++ unsigned int nandCapacity; ++ struct rknand_chip rknand; ++ int (*ftl_cache_en)(int en); ++ int (*ftl_read) (int Index, int nSec, void *buf); ++ int (*ftl_write) (int Index, int nSec, void *buf ,int mode); ++ int (*ftl_write_panic) (int Index, int nSec, void *buf); ++ int (*ftl_close)(void); ++ int (*ftl_sync)(void); ++ int (*proc_bufread)(char *page); ++ int (*proc_ftlread)(char *page); ++ int (*rknand_schedule_enable)(int en); ++ int (*add_rknand_device)(struct rknand_info * prknand_Info); ++ int (*get_rknand_device)(struct rknand_info ** prknand_Info); ++ void (*rknand_buffer_shutdown)(void); ++ int (*GetIdBlockSysData)(char * buf, int Sector); ++ char (*GetSNSectorInfo)(char * pbuf); ++ char (*GetChipSectorInfo)(char * pbuf); ++ int emmc_clk_power_save_en; ++ char *pdmaBuf; ++ void (*nand_timing_config)(unsigned long AHBnKHz); ++ void (*rknand_suspend)(void); ++ void (*rknand_resume)(void); ++ int (*rknand_re_init)(void); ++ void (*rknand_dev_cache_flush)(void); ++ int (*ftl_discard) (int Index, int nSec); ++ int reserved[20]; ++}; ++ ++extern int rknand_queue_read(int Index, int nSec, void *buf); ++extern int rknand_queue_write(int Index, int nSec, void *buf,int mode); ++extern int rknand_buffer_init(char * pbuf,int size); ++extern void rknand_buffer_data_init(void); ++extern void rknand_buffer_shutdown(void); ++extern int add_rknand_device(struct rknand_info * prknand_Info); ++extern int get_rknand_device(struct rknand_info ** prknand_Info); ++extern int rknand_buffer_sync(void); ++extern void rknand_cache_flush(void); ++extern void rknand_dev_cache_flush(void); ++ ++#endif diff --git a/drivers/mtd/rknand/rknand_base_ko.c b/drivers/mtd/rknand/rknand_base_ko.c new file mode 100644 index 000000000..8b0c0f5ef @@ -911876,704 +911876,704 @@ index 000000000..8b0c0f5ef +++ b/drivers/mtd/rknand/rknand_base_ko.c @@ -0,0 +1,699 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+/* -+ * linux/drivers/mtd/rknand/rknand_base.c -+ * -+ * Copyright (C) 2005-2009 Fuzhou Rockchip Electronics -+ * ZYF -+ * -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//#include "api_flash.h" -+#include "rknand_base.h" -+#include "../mtdcore.h" -+#include -+#include -+#ifdef CONFIG_OF -+#include -+#endif -+ -+#define DRIVER_NAME "rk29xxnand" -+ -+const char rknand_base_version[] = "rknand_base.c version: 4.38 20120717"; -+#define NAND_DEBUG_LEVEL0 0 -+#define NAND_DEBUG_LEVEL1 1 -+#define NAND_DEBUG_LEVEL2 2 -+#define NAND_DEBUG_LEVEL3 3 -+ -+int g_num_partitions = 0; -+unsigned long SysImageWriteEndAdd = 0; -+struct mtd_info rknand_mtd; -+struct mtd_partition *rknand_parts; -+struct rknand_info * gpNandInfo; -+ -+#ifdef CONFIG_MTD_NAND_RK29XX_DEBUG -+static int s_debug = CONFIG_MTD_NAND_RK29XX_DEBUG_VERBOSE; -+#undef NAND_DEBUG -+#define NAND_DEBUG(n, format, arg...) \ -+ if (n <= s_debug) { \ -+ printk(format,##arg); \ -+ } -+#else -+#undef NAND_DEBUG -+#define NAND_DEBUG(n, arg...) -+static const int s_debug = 0; -+#endif -+ -+#include -+#include -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) -+#define NANDPROC_ROOT (&proc_root) -+#else -+#define NANDPROC_ROOT NULL -+#endif -+ -+//#define RKNAND_TRAC_EN -+#ifdef RKNAND_TRAC_EN -+static struct proc_dir_entry *my_trac_proc_entry; -+#define MAX_TRAC_BUFFER_SIZE (long)(2048 * 8 * 512) //sector -+static char grknand_trac_buf[MAX_TRAC_BUFFER_SIZE]; -+static char *ptrac_buf = grknand_trac_buf; -+void trac_log(long lba,int len, int mod) -+{ -+ unsigned long long t; -+ unsigned long nanosec_rem; -+ t = cpu_clock(UINT_MAX); -+ nanosec_rem = do_div(t, 1000000000); -+ if(mod) -+ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] W %d %d \n",(unsigned long) t, nanosec_rem / 1000,lba,len); -+ else -+ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] R %d %d \n",(unsigned long) t, nanosec_rem / 1000,lba,len); -+} -+ -+void trac_logs(char *s) -+{ -+ unsigned long long t; -+ unsigned long nanosec_rem; -+ t = cpu_clock(UINT_MAX); -+ nanosec_rem = do_div(t, 1000000000); -+ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] %s\n",(unsigned long) t, nanosec_rem / 1000,s); -+} -+ -+static int rkNand_trac_read(char *page, char **start, off_t off, int count, int *eof, -+ void *data) -+{ -+ char *p = page; -+ int len; -+ -+ len = ptrac_buf - grknand_trac_buf - off; -+ //printk("rkNand_trac_read: page=%x,off=%x,count=%x ,len=%x \n",(int)page,(int)off,count,len); -+ -+ if (len < 0) -+ len = 0; -+ -+ if(len > count) -+ len = count; -+ -+ memcpy(p,grknand_trac_buf + off,len); -+ -+ *eof = (len < count) ? 1 : 0; -+ *start = page; -+ if(len < count) -+ ptrac_buf = grknand_trac_buf; -+ return len; -+} -+ -+#endif -+ -+#define DATA_LEN (1024*8*2/4) //???ݿ鵥λword -+#define SPARE_LEN (32*8*2/4) //У?????ݳ??? -+#define PAGE_LEN (DATA_LEN+SPARE_LEN) //ÿ?????ݵ?λ?ij??? -+#define MAX_BUFFER_SIZE (long)(2048 * 8) //sector -+//long grknand_buf[MAX_BUFFER_SIZE * 512/4] __attribute__((aligned(4096))); -+//long grknand_dma_buf[PAGE_LEN*4*5] __attribute__((aligned(4096))); -+static struct proc_dir_entry *my_proc_entry; -+extern int rkNand_proc_ftlread(char *page); -+extern int rkNand_proc_bufread(char *page); -+static int rkNand_proc_read(char *page, -+ char **start, -+ off_t offset, int count, int *eof, void *data) -+{ -+ char *buf = page; -+ int step = offset; -+ *(int *)start = 1; -+ if(step == 0) -+ { -+ buf += sprintf(buf, "%s\n", rknand_base_version); -+ if(gpNandInfo->proc_ftlread) -+ buf += gpNandInfo->proc_ftlread(buf); -+ if(gpNandInfo->proc_bufread) -+ buf += gpNandInfo->proc_bufread(buf); -+#ifdef RKNAND_TRAC_EN -+ buf += sprintf(buf, "trac data len:%d\n", ptrac_buf - grknand_trac_buf); -+#endif -+ } -+ return buf - page < count ? buf - page : count; -+} -+ -+#if 0// (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)) -+static void rknand_create_procfs(void) -+{ -+ /* Install the proc_fs entry */ -+ my_proc_entry = create_proc_entry("rknand", -+ S_IRUGO | S_IFREG, -+ NANDPROC_ROOT); -+ -+ if (my_proc_entry) { -+ my_proc_entry->write_proc = NULL; -+ my_proc_entry->read_proc = rkNand_proc_read; -+ my_proc_entry->data = NULL; -+ } -+#ifdef RKNAND_TRAC_EN -+ /* Install the proc_fs entry */ -+ my_trac_proc_entry = create_proc_entry("rknand_trac", -+ S_IRUGO | S_IFREG, -+ NANDPROC_ROOT); -+ if (my_trac_proc_entry) { -+ my_trac_proc_entry->write_proc = NULL; -+ my_trac_proc_entry->read_proc = rkNand_trac_read; -+ my_trac_proc_entry->data = NULL; -+ } -+#endif -+} -+#else -+static const struct file_operations my_proc_fops = { -+.owner = THIS_MODULE, -+.read = rkNand_proc_read, -+.write = NULL, -+}; -+ -+static void rknand_create_procfs(void) -+{ -+ /* Install the proc_fs entry */ -+ my_proc_entry = proc_create("rknand", -+ S_IRUGO | S_IFREG, -+ NANDPROC_ROOT,&my_proc_fops); -+} -+#endif -+void printk_write_log(long lba,int len, const u_char *pbuf) -+{ -+ char debug_buf[100]; -+ int i; -+ for(i=0;i>9; -+ int LBA = (int)(from>>9); -+#ifdef RKNAND_TRAC_EN -+ //trac_log(LBA,sector,0); -+#endif -+ //printk("R %d %d \n",(int)LBA,sector); -+ //if(rknand_debug) -+ // printk("rk28xxnand_read: from=%x,sector=%x,\n",(int)LBA,sector); -+ if(sector && gpNandInfo->ftl_read) -+ { -+ ret = gpNandInfo->ftl_read(LBA, sector, buf); -+ if(ret) -+ *retlen = 0; -+ } -+ return ret; -+} -+ -+static int rknand_write(struct mtd_info *mtd, loff_t from, size_t len, -+ size_t *retlen, const u_char *buf) -+{ -+ int ret = 0; -+ int sector = len>>9; -+ int LBA = (int)(from>>9); -+#ifdef RKNAND_TRAC_EN -+ trac_log(LBA,sector,1); -+#endif -+ //printk("W %d %d \n",(int)LBA,sector); -+ //return 0; -+ //printk("*"); -+ //if(rknand_debug) -+ // printk(KERN_NOTICE "write: from=%lx,sector=%x\n",(int)LBA,sector); -+ //printk_write_log(LBA,sector,buf); -+ if(sector && gpNandInfo->ftl_write)// cmy -+ { -+ if(LBA < SysImageWriteEndAdd)//0x4E000) -+ { -+ //NAND_DEBUG(NAND_DEBUG_LEVEL0,">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector); -+ ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,1); -+ } -+ else -+ { -+ ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,0); -+ } -+ } -+ *retlen = len; -+ return 0; -+} -+ -+static int rknand_diacard(struct mtd_info *mtd, loff_t from, size_t len) -+{ -+ int ret = 0; -+ int sector = len>>9; -+ int LBA = (int)(from>>9); -+ //printk("rknand_diacard: from=%x,sector=%x,\n",(int)LBA,sector); -+ if(sector && gpNandInfo->ftl_discard) -+ { -+ ret = gpNandInfo->ftl_discard(LBA, sector); -+ } -+ return ret; -+} -+ -+static int rknand_erase(struct mtd_info *mtd, struct erase_info *instr) -+{ -+ int ret = 0; -+ if (instr->callback) -+ instr->callback(instr); -+ return ret; -+} -+ -+static void rknand_sync(struct mtd_info *mtd) -+{ -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk_nand_sync: \n"); -+ if(gpNandInfo->ftl_sync) -+ gpNandInfo->ftl_sync(); -+} -+ -+extern void FtlWriteCacheEn(int); -+static int rknand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) -+{ -+ int sector = len >> 9; -+ int LBA = (int)(to >> 9); -+ -+ if (sector && gpNandInfo->ftl_write_panic) { -+ if(gpNandInfo->ftl_cache_en) -+ gpNandInfo->ftl_cache_en(0); -+ gpNandInfo->ftl_write_panic(LBA, sector, (void *)buf); -+ if(gpNandInfo->ftl_cache_en) -+ gpNandInfo->ftl_cache_en(1); -+ } -+ *retlen = len; -+ return 0; -+} -+ -+ -+int GetIdBlockSysData(char * buf, int Sector) -+{ -+ if(gpNandInfo->GetIdBlockSysData) -+ return( gpNandInfo->GetIdBlockSysData( buf, Sector)); -+ return 0; -+} -+ -+char GetSNSectorInfoBeforeNandInit(char * pbuf) -+{ -+ char * sn_addr = ioremap(0x10501600,0x200); -+ memcpy(pbuf,sn_addr,0x200); -+ iounmap(sn_addr); -+ //print_hex_dump(KERN_WARNING, "sn:", DUMP_PREFIX_NONE, 16,1, sn_addr, 16, 0); -+ return 0; -+} -+ -+char GetSNSectorInfo(char * pbuf) -+{ -+ if(gpNandInfo->GetSNSectorInfo) -+ return( gpNandInfo->GetSNSectorInfo( pbuf)); -+ else -+ return GetSNSectorInfoBeforeNandInit(pbuf); -+ return 0; -+} -+ -+ -+char GetVendor0InfoBeforeNandInit(char * pbuf) -+{ -+ char * sn_addr = ioremap(0x10501400,0x200); -+ memcpy(pbuf,sn_addr + 8,504); -+ iounmap(sn_addr); -+ //print_hex_dump(KERN_WARNING, "sn:", DUMP_PREFIX_NONE, 16,1, sn_addr, 16, 0); -+ return 0; -+} -+ -+char GetChipSectorInfo(char * pbuf) -+{ -+ if(gpNandInfo->GetChipSectorInfo) -+ return( gpNandInfo->GetChipSectorInfo( pbuf)); -+ return 0; -+} -+ -+int GetParamterInfo(char * pbuf , int len) -+{ -+ int ret = -1; -+ int sector = (len)>>9; -+ int LBA = 0; -+ if(sector && gpNandInfo->ftl_read) -+ { -+ ret = gpNandInfo->ftl_read(LBA, sector, pbuf); -+ } -+ return ret?-1:(sector<<9); -+} -+ -+int GetflashDataByLba(int lba,char * pbuf , int len) -+{ -+ int ret = -1; -+ int sector = (len)>>9; -+ int LBA = lba; -+ if(sector && gpNandInfo->ftl_read) -+ { -+ ret = gpNandInfo->ftl_read(LBA, sector, pbuf); -+ } -+ return ret?-1:(sector<<9); -+} -+ -+void rknand_dev_cache_flush(void) -+{ -+ if(gpNandInfo->rknand_dev_cache_flush) -+ gpNandInfo->rknand_dev_cache_flush(); -+} -+ -+ -+static int rknand_block_isbad(struct mtd_info *mtd, loff_t ofs) -+{ -+ return 0; -+} -+ -+static int rknand_block_markbad(struct mtd_info *mtd, loff_t ofs) -+{ -+ return 0; -+} -+ -+ -+static struct clk *nandc_clk; -+static unsigned long nandc_clk_rate = 0; -+static struct notifier_block nandc_freq_transition; -+/* cpufreq driver support */ -+static int rknand_nand_timing_cfg(void) -+{ -+ unsigned long newclk; -+ newclk = clk_get_rate(nandc_clk); -+ //printk("rknand_nand_timing_cfg %d",newclk); -+ if (newclk != nandc_clk_rate) -+ { -+ if(gpNandInfo->nand_timing_config) -+ { -+ nandc_clk_rate = newclk; -+ //gpNandInfo->nand_timing_config( nandc_clk_rate / 1000); // KHz -+ } -+ } -+ return 0; -+} -+ -+static int rknand_info_init(struct rknand_info *nand_info) -+{ -+ struct mtd_info *mtd = &rknand_mtd; -+ struct rknand_chip *rknand = &nand_info->rknand; -+ -+ rknand->state = FL_READY; -+ rknand->rknand_schedule_enable = 1; -+ rknand->pFlashCallBack = NULL; -+ init_waitqueue_head(&rknand->wq); -+ -+ mtd->oobsize = 0; -+ mtd->oobavail = 0; -+ mtd->ecclayout = 0; -+ mtd->erasesize = 32*0x200; -+ mtd->writesize = 8*0x200; -+ -+ // Fill in remaining MTD driver data -+ mtd->type = MTD_NANDFLASH; -+ mtd->flags = (MTD_WRITEABLE|MTD_NO_ERASE);// -+ mtd->_erase = rknand_erase; -+ mtd->_point = NULL; -+ mtd->_unpoint = NULL; -+ mtd->_read = rknand_read; -+ mtd->_write = rknand_write; -+ //mtd->discard = rknand_diacard; -+ mtd->_read_oob = NULL; -+ mtd->_write_oob = NULL; -+ mtd->_panic_write = rknand_panic_write; -+ -+ mtd->_sync = rknand_sync; -+ mtd->_lock = NULL; -+ mtd->_unlock = NULL; -+ mtd->_suspend = NULL; -+ mtd->_resume = NULL; -+ mtd->_block_isbad = rknand_block_isbad; -+ mtd->_block_markbad = rknand_block_markbad; -+ mtd->owner = THIS_MODULE; -+ return 0; -+} -+ -+ -+/* -+ * CMY: ?????˶??????з?????Ï¢??Ö§?? -+ * ??cmdline???ṩ??????Ï¢????ʹ??cmdline?Ä·?????Ï¢???з??? -+ * ??cmdlineû???ṩ??????Ï¢????ʹ??Ĭ?ϵķ?????Ï¢(rk28_partition_info)???з??? -+ */ -+ -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+const char *part_probes[] = { "cmdlinepart", NULL }; -+#endif -+ -+static int rknand_add_partitions(struct rknand_info *nand_info) -+{ -+#ifdef CONFIG_MTD_CMDLINE_PARTS -+ int num_partitions = 0; -+ -+ // ???????н???????????Ï¢ -+ num_partitions = parse_mtd_partitions(&(rknand_mtd), part_probes, &rknand_parts, 0); -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"num_partitions = %d\n",num_partitions); -+ printk("num_partitions = %d\n",num_partitions); -+ if(num_partitions > 0) { -+ int i; -+ for (i = 0; i < num_partitions; i++) -+ { -+ rknand_parts[i].offset *= 0x200; -+ rknand_parts[i].size *=0x200; -+ } -+ rknand_parts[num_partitions - 1].size = rknand_mtd.size - rknand_parts[num_partitions - 1].offset; -+ -+ g_num_partitions = num_partitions; -+//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) -+// return mtd_device_register(&rknand_mtd, rknand_parts, num_partitions); -+//#else -+ return add_mtd_partitions(&(rknand_mtd), rknand_parts, num_partitions); -+//#endif -+ } -+#endif -+ g_num_partitions = 0; -+ return 0; -+} -+ -+int add_rknand_device(struct rknand_info * prknand_Info) -+{ -+ struct mtd_partition *parts; -+ int i; -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"add_rknand_device: \n"); -+ printk("gpNandInfo->nandCapacity = %lx\n",gpNandInfo->nandCapacity); -+ rknand_mtd.size = (uint64_t)gpNandInfo->nandCapacity*0x200; -+ -+ rknand_add_partitions(prknand_Info); -+ -+ parts = rknand_parts; -+ SysImageWriteEndAdd = 0; -+ for(i=0;i>> part[%d]: name=%s offset=0x%012llx\n", i, parts[i].name, parts[i].offset); -+ if(strcmp(parts[i].name,"backup") == 0) -+ { -+ SysImageWriteEndAdd = (unsigned long)(parts[i].offset + parts[i].size)>>9;//sector -+ //printk(">>> SysImageWriteEndAdd=0x%lx\n", SysImageWriteEndAdd); -+ break; -+ } -+ } -+ if(SysImageWriteEndAdd) -+ gpNandInfo->SysImageWriteEndAdd = SysImageWriteEndAdd; -+ -+ //nandc_clk = clk_get(NULL, "nandc"); -+ //clk_enable(nandc_clk); -+ //rknand_nand_timing_cfg(); -+ -+ return 0; -+} -+ -+int get_rknand_device(struct rknand_info ** prknand_Info) -+{ -+ *prknand_Info = gpNandInfo; -+ return 0; -+} -+ -+EXPORT_SYMBOL(get_rknand_device); -+ -+int rknand_dma_map_single(unsigned long ptr,int size,int dir) -+{ -+ return dma_map_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE); -+} -+EXPORT_SYMBOL(rknand_dma_map_single); -+ -+void rknand_dma_unmap_single(unsigned long ptr,int size,int dir) -+{ -+ dma_unmap_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE); -+} -+EXPORT_SYMBOL(rknand_dma_unmap_single); -+ -+int rknand_flash_cs_init(void) -+{ -+ -+} -+EXPORT_SYMBOL(rknand_flash_cs_init); -+ -+ -+int rknand_get_reg_addr(int *pNandc,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2) -+{ -+ //*pNandc = ioremap(RK30_NANDC_PHYS,RK30_NANDC_SIZE); -+ //*pSDMMC0 = ioremap(SDMMC0_BASE_ADDR, 0x4000); -+ //*pSDMMC1 = ioremap(SDMMC1_BASE_ADDR, 0x4000); -+ //*pSDMMC2 = ioremap(EMMC_BASE_ADDR, 0x4000); -+ *pNandc = ioremap(0x10500000,0x4000); -+} -+EXPORT_SYMBOL(rknand_get_reg_addr); -+ -+static int g_nandc_irq = 27; -+int rknand_nandc_irq_init(int mode,void * pfun) -+{ -+ int ret = 0; -+ if(mode) //init -+ { -+ ret = request_irq(g_nandc_irq, pfun, 0, "nandc", NULL); -+ if(ret) -+ printk("request IRQ_NANDC irq , ret=%x.........\n", ret); -+ } -+ else //deinit -+ { -+ free_irq(g_nandc_irq, NULL); -+ } -+ return ret; -+} -+EXPORT_SYMBOL(rknand_nandc_irq_init); -+static int rknand_probe(struct platform_device *pdev) -+{ -+ struct rknand_info *nand_info; -+ int err = 0; -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk_nand_probe: \n"); -+ gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL); -+ if (!gpNandInfo) -+ return -ENOMEM; -+ -+ nand_info = gpNandInfo; -+ printk("rknand_probe: \n"); -+ -+ g_nandc_irq = platform_get_irq(pdev, 0); -+ if (g_nandc_irq < 0) { -+ dev_err(&pdev->dev, "no irq resource?\n"); -+ return g_nandc_irq; -+ } -+ -+ memset(gpNandInfo,0,sizeof(struct rknand_info)); -+ -+ gpNandInfo->bufSize = MAX_BUFFER_SIZE * 512; -+ gpNandInfo->pbuf = (char *)NULL;//grknand_buf; -+ gpNandInfo->pdmaBuf = (char *)NULL;//grknand_dma_buf; -+ //printk(" gpNandInfo->pdmaBuf=0x%x\n", gpNandInfo->pdmaBuf); -+#ifdef CONFIG_MTD_EMMC_CLK_POWER_SAVE -+ gpNandInfo->emmc_clk_power_save_en = 1; -+#endif -+ -+ rknand_mtd.name = DRIVER_NAME;//dev_name(&pdev->dev); -+ rknand_mtd.priv = &nand_info->rknand; -+ rknand_mtd.owner = THIS_MODULE; -+ -+ if(rknand_info_init(nand_info)) -+ { -+ err = -ENXIO; -+ goto exit_free; -+ } -+ -+ nand_info->add_rknand_device = add_rknand_device; -+ nand_info->get_rknand_device = get_rknand_device; -+ -+ rknand_create_procfs(); -+ return 0; -+ -+exit_free: -+ if(nand_info) -+ kfree(nand_info); -+ -+ return err; -+} -+ -+static int rknand_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ gpNandInfo->rknand.rknand_schedule_enable = 0; -+ // if(gpNandInfo->rknand_suspend) -+ // gpNandInfo->rknand_suspend(); -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_suspend: \n"); -+ return 0; -+} -+ -+static int rknand_resume(struct platform_device *pdev) -+{ -+ //if(gpNandInfo->rknand_resume) -+ // gpNandInfo->rknand_resume(); -+ gpNandInfo->rknand.rknand_schedule_enable = 1; -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_resume: \n"); -+ return 0; -+} -+ -+void rknand_shutdown(struct platform_device *pdev) -+{ -+ printk("rknand_shutdown...\n"); -+ gpNandInfo->rknand.rknand_schedule_enable = 0; -+ if(gpNandInfo->rknand_buffer_shutdown) -+ gpNandInfo->rknand_buffer_shutdown(); -+} -+ -+#ifdef CONFIG_OF -+static const struct of_device_id of_rk_nandc_match[] = { -+ { .compatible = "rockchip,rk-nandc" }, -+ { /* Sentinel */ } -+}; -+#endif -+ -+static struct platform_driver rknand_driver = { -+ .probe = rknand_probe, -+ .suspend = rknand_suspend, -+ .resume = rknand_resume, -+ .shutdown = rknand_shutdown, -+ .driver = { -+ .name = DRIVER_NAME, -+#ifdef CONFIG_OF -+ .of_match_table = of_rk_nandc_match, -+#endif -+ .owner = THIS_MODULE, -+ }, -+}; -+ -+ -+MODULE_ALIAS(DRIVER_NAME); -+ -+static int __init rknand_init(void) -+{ -+ int ret; -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_init: \n"); -+ ret = platform_driver_register(&rknand_driver); -+ NAND_DEBUG(NAND_DEBUG_LEVEL0,"platform_driver_register:ret = %x \n",ret); -+ return ret; -+} -+ -+static void __exit rknand_exit(void) -+{ -+ platform_driver_unregister(&rknand_driver); -+} -+ -+module_init(rknand_init); -+module_exit(rknand_exit); -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("ZYF "); -+MODULE_DESCRIPTION("rknand driver."); -+ -+ ++/* ++ * linux/drivers/mtd/rknand/rknand_base.c ++ * ++ * Copyright (C) 2005-2009 Fuzhou Rockchip Electronics ++ * ZYF ++ * ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++//#include "api_flash.h" ++#include "rknand_base.h" ++#include "../mtdcore.h" ++#include ++#include ++#ifdef CONFIG_OF ++#include ++#endif ++ ++#define DRIVER_NAME "rk29xxnand" ++ ++const char rknand_base_version[] = "rknand_base.c version: 4.38 20120717"; ++#define NAND_DEBUG_LEVEL0 0 ++#define NAND_DEBUG_LEVEL1 1 ++#define NAND_DEBUG_LEVEL2 2 ++#define NAND_DEBUG_LEVEL3 3 ++ ++int g_num_partitions = 0; ++unsigned long SysImageWriteEndAdd = 0; ++struct mtd_info rknand_mtd; ++struct mtd_partition *rknand_parts; ++struct rknand_info * gpNandInfo; ++ ++#ifdef CONFIG_MTD_NAND_RK29XX_DEBUG ++static int s_debug = CONFIG_MTD_NAND_RK29XX_DEBUG_VERBOSE; ++#undef NAND_DEBUG ++#define NAND_DEBUG(n, format, arg...) \ ++ if (n <= s_debug) { \ ++ printk(format,##arg); \ ++ } ++#else ++#undef NAND_DEBUG ++#define NAND_DEBUG(n, arg...) ++static const int s_debug = 0; ++#endif ++ ++#include ++#include ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26)) ++#define NANDPROC_ROOT (&proc_root) ++#else ++#define NANDPROC_ROOT NULL ++#endif ++ ++//#define RKNAND_TRAC_EN ++#ifdef RKNAND_TRAC_EN ++static struct proc_dir_entry *my_trac_proc_entry; ++#define MAX_TRAC_BUFFER_SIZE (long)(2048 * 8 * 512) //sector ++static char grknand_trac_buf[MAX_TRAC_BUFFER_SIZE]; ++static char *ptrac_buf = grknand_trac_buf; ++void trac_log(long lba,int len, int mod) ++{ ++ unsigned long long t; ++ unsigned long nanosec_rem; ++ t = cpu_clock(UINT_MAX); ++ nanosec_rem = do_div(t, 1000000000); ++ if(mod) ++ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] W %d %d \n",(unsigned long) t, nanosec_rem / 1000,lba,len); ++ else ++ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] R %d %d \n",(unsigned long) t, nanosec_rem / 1000,lba,len); ++} ++ ++void trac_logs(char *s) ++{ ++ unsigned long long t; ++ unsigned long nanosec_rem; ++ t = cpu_clock(UINT_MAX); ++ nanosec_rem = do_div(t, 1000000000); ++ ptrac_buf += sprintf(ptrac_buf,"[%5lu.%06lu] %s\n",(unsigned long) t, nanosec_rem / 1000,s); ++} ++ ++static int rkNand_trac_read(char *page, char **start, off_t off, int count, int *eof, ++ void *data) ++{ ++ char *p = page; ++ int len; ++ ++ len = ptrac_buf - grknand_trac_buf - off; ++ //printk("rkNand_trac_read: page=%x,off=%x,count=%x ,len=%x \n",(int)page,(int)off,count,len); ++ ++ if (len < 0) ++ len = 0; ++ ++ if(len > count) ++ len = count; ++ ++ memcpy(p,grknand_trac_buf + off,len); ++ ++ *eof = (len < count) ? 1 : 0; ++ *start = page; ++ if(len < count) ++ ptrac_buf = grknand_trac_buf; ++ return len; ++} ++ ++#endif ++ ++#define DATA_LEN (1024*8*2/4) //???ݿ鵥λword ++#define SPARE_LEN (32*8*2/4) //У?????ݳ??? ++#define PAGE_LEN (DATA_LEN+SPARE_LEN) //ÿ?????ݵ?λ?ij??? ++#define MAX_BUFFER_SIZE (long)(2048 * 8) //sector ++//long grknand_buf[MAX_BUFFER_SIZE * 512/4] __attribute__((aligned(4096))); ++//long grknand_dma_buf[PAGE_LEN*4*5] __attribute__((aligned(4096))); ++static struct proc_dir_entry *my_proc_entry; ++extern int rkNand_proc_ftlread(char *page); ++extern int rkNand_proc_bufread(char *page); ++static int rkNand_proc_read(char *page, ++ char **start, ++ off_t offset, int count, int *eof, void *data) ++{ ++ char *buf = page; ++ int step = offset; ++ *(int *)start = 1; ++ if(step == 0) ++ { ++ buf += sprintf(buf, "%s\n", rknand_base_version); ++ if(gpNandInfo->proc_ftlread) ++ buf += gpNandInfo->proc_ftlread(buf); ++ if(gpNandInfo->proc_bufread) ++ buf += gpNandInfo->proc_bufread(buf); ++#ifdef RKNAND_TRAC_EN ++ buf += sprintf(buf, "trac data len:%d\n", ptrac_buf - grknand_trac_buf); ++#endif ++ } ++ return buf - page < count ? buf - page : count; ++} ++ ++#if 0// (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0)) ++static void rknand_create_procfs(void) ++{ ++ /* Install the proc_fs entry */ ++ my_proc_entry = create_proc_entry("rknand", ++ S_IRUGO | S_IFREG, ++ NANDPROC_ROOT); ++ ++ if (my_proc_entry) { ++ my_proc_entry->write_proc = NULL; ++ my_proc_entry->read_proc = rkNand_proc_read; ++ my_proc_entry->data = NULL; ++ } ++#ifdef RKNAND_TRAC_EN ++ /* Install the proc_fs entry */ ++ my_trac_proc_entry = create_proc_entry("rknand_trac", ++ S_IRUGO | S_IFREG, ++ NANDPROC_ROOT); ++ if (my_trac_proc_entry) { ++ my_trac_proc_entry->write_proc = NULL; ++ my_trac_proc_entry->read_proc = rkNand_trac_read; ++ my_trac_proc_entry->data = NULL; ++ } ++#endif ++} ++#else ++static const struct file_operations my_proc_fops = { ++.owner = THIS_MODULE, ++.read = rkNand_proc_read, ++.write = NULL, ++}; ++ ++static void rknand_create_procfs(void) ++{ ++ /* Install the proc_fs entry */ ++ my_proc_entry = proc_create("rknand", ++ S_IRUGO | S_IFREG, ++ NANDPROC_ROOT,&my_proc_fops); ++} ++#endif ++void printk_write_log(long lba,int len, const u_char *pbuf) ++{ ++ char debug_buf[100]; ++ int i; ++ for(i=0;i>9; ++ int LBA = (int)(from>>9); ++#ifdef RKNAND_TRAC_EN ++ //trac_log(LBA,sector,0); ++#endif ++ //printk("R %d %d \n",(int)LBA,sector); ++ //if(rknand_debug) ++ // printk("rk28xxnand_read: from=%x,sector=%x,\n",(int)LBA,sector); ++ if(sector && gpNandInfo->ftl_read) ++ { ++ ret = gpNandInfo->ftl_read(LBA, sector, buf); ++ if(ret) ++ *retlen = 0; ++ } ++ return ret; ++} ++ ++static int rknand_write(struct mtd_info *mtd, loff_t from, size_t len, ++ size_t *retlen, const u_char *buf) ++{ ++ int ret = 0; ++ int sector = len>>9; ++ int LBA = (int)(from>>9); ++#ifdef RKNAND_TRAC_EN ++ trac_log(LBA,sector,1); ++#endif ++ //printk("W %d %d \n",(int)LBA,sector); ++ //return 0; ++ //printk("*"); ++ //if(rknand_debug) ++ // printk(KERN_NOTICE "write: from=%lx,sector=%x\n",(int)LBA,sector); ++ //printk_write_log(LBA,sector,buf); ++ if(sector && gpNandInfo->ftl_write)// cmy ++ { ++ if(LBA < SysImageWriteEndAdd)//0x4E000) ++ { ++ //NAND_DEBUG(NAND_DEBUG_LEVEL0,">>> FtlWriteImage: LBA=0x%08X sector=%d\n",LBA, sector); ++ ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,1); ++ } ++ else ++ { ++ ret = gpNandInfo->ftl_write(LBA, sector, (void *)buf,0); ++ } ++ } ++ *retlen = len; ++ return 0; ++} ++ ++static int rknand_diacard(struct mtd_info *mtd, loff_t from, size_t len) ++{ ++ int ret = 0; ++ int sector = len>>9; ++ int LBA = (int)(from>>9); ++ //printk("rknand_diacard: from=%x,sector=%x,\n",(int)LBA,sector); ++ if(sector && gpNandInfo->ftl_discard) ++ { ++ ret = gpNandInfo->ftl_discard(LBA, sector); ++ } ++ return ret; ++} ++ ++static int rknand_erase(struct mtd_info *mtd, struct erase_info *instr) ++{ ++ int ret = 0; ++ if (instr->callback) ++ instr->callback(instr); ++ return ret; ++} ++ ++static void rknand_sync(struct mtd_info *mtd) ++{ ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk_nand_sync: \n"); ++ if(gpNandInfo->ftl_sync) ++ gpNandInfo->ftl_sync(); ++} ++ ++extern void FtlWriteCacheEn(int); ++static int rknand_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf) ++{ ++ int sector = len >> 9; ++ int LBA = (int)(to >> 9); ++ ++ if (sector && gpNandInfo->ftl_write_panic) { ++ if(gpNandInfo->ftl_cache_en) ++ gpNandInfo->ftl_cache_en(0); ++ gpNandInfo->ftl_write_panic(LBA, sector, (void *)buf); ++ if(gpNandInfo->ftl_cache_en) ++ gpNandInfo->ftl_cache_en(1); ++ } ++ *retlen = len; ++ return 0; ++} ++ ++ ++int GetIdBlockSysData(char * buf, int Sector) ++{ ++ if(gpNandInfo->GetIdBlockSysData) ++ return( gpNandInfo->GetIdBlockSysData( buf, Sector)); ++ return 0; ++} ++ ++char GetSNSectorInfoBeforeNandInit(char * pbuf) ++{ ++ char * sn_addr = ioremap(0x10501600,0x200); ++ memcpy(pbuf,sn_addr,0x200); ++ iounmap(sn_addr); ++ //print_hex_dump(KERN_WARNING, "sn:", DUMP_PREFIX_NONE, 16,1, sn_addr, 16, 0); ++ return 0; ++} ++ ++char GetSNSectorInfo(char * pbuf) ++{ ++ if(gpNandInfo->GetSNSectorInfo) ++ return( gpNandInfo->GetSNSectorInfo( pbuf)); ++ else ++ return GetSNSectorInfoBeforeNandInit(pbuf); ++ return 0; ++} ++ ++ ++char GetVendor0InfoBeforeNandInit(char * pbuf) ++{ ++ char * sn_addr = ioremap(0x10501400,0x200); ++ memcpy(pbuf,sn_addr + 8,504); ++ iounmap(sn_addr); ++ //print_hex_dump(KERN_WARNING, "sn:", DUMP_PREFIX_NONE, 16,1, sn_addr, 16, 0); ++ return 0; ++} ++ ++char GetChipSectorInfo(char * pbuf) ++{ ++ if(gpNandInfo->GetChipSectorInfo) ++ return( gpNandInfo->GetChipSectorInfo( pbuf)); ++ return 0; ++} ++ ++int GetParamterInfo(char * pbuf , int len) ++{ ++ int ret = -1; ++ int sector = (len)>>9; ++ int LBA = 0; ++ if(sector && gpNandInfo->ftl_read) ++ { ++ ret = gpNandInfo->ftl_read(LBA, sector, pbuf); ++ } ++ return ret?-1:(sector<<9); ++} ++ ++int GetflashDataByLba(int lba,char * pbuf , int len) ++{ ++ int ret = -1; ++ int sector = (len)>>9; ++ int LBA = lba; ++ if(sector && gpNandInfo->ftl_read) ++ { ++ ret = gpNandInfo->ftl_read(LBA, sector, pbuf); ++ } ++ return ret?-1:(sector<<9); ++} ++ ++void rknand_dev_cache_flush(void) ++{ ++ if(gpNandInfo->rknand_dev_cache_flush) ++ gpNandInfo->rknand_dev_cache_flush(); ++} ++ ++ ++static int rknand_block_isbad(struct mtd_info *mtd, loff_t ofs) ++{ ++ return 0; ++} ++ ++static int rknand_block_markbad(struct mtd_info *mtd, loff_t ofs) ++{ ++ return 0; ++} ++ ++ ++static struct clk *nandc_clk; ++static unsigned long nandc_clk_rate = 0; ++static struct notifier_block nandc_freq_transition; ++/* cpufreq driver support */ ++static int rknand_nand_timing_cfg(void) ++{ ++ unsigned long newclk; ++ newclk = clk_get_rate(nandc_clk); ++ //printk("rknand_nand_timing_cfg %d",newclk); ++ if (newclk != nandc_clk_rate) ++ { ++ if(gpNandInfo->nand_timing_config) ++ { ++ nandc_clk_rate = newclk; ++ //gpNandInfo->nand_timing_config( nandc_clk_rate / 1000); // KHz ++ } ++ } ++ return 0; ++} ++ ++static int rknand_info_init(struct rknand_info *nand_info) ++{ ++ struct mtd_info *mtd = &rknand_mtd; ++ struct rknand_chip *rknand = &nand_info->rknand; ++ ++ rknand->state = FL_READY; ++ rknand->rknand_schedule_enable = 1; ++ rknand->pFlashCallBack = NULL; ++ init_waitqueue_head(&rknand->wq); ++ ++ mtd->oobsize = 0; ++ mtd->oobavail = 0; ++ mtd->ecclayout = 0; ++ mtd->erasesize = 32*0x200; ++ mtd->writesize = 8*0x200; ++ ++ // Fill in remaining MTD driver data ++ mtd->type = MTD_NANDFLASH; ++ mtd->flags = (MTD_WRITEABLE|MTD_NO_ERASE);// ++ mtd->_erase = rknand_erase; ++ mtd->_point = NULL; ++ mtd->_unpoint = NULL; ++ mtd->_read = rknand_read; ++ mtd->_write = rknand_write; ++ //mtd->discard = rknand_diacard; ++ mtd->_read_oob = NULL; ++ mtd->_write_oob = NULL; ++ mtd->_panic_write = rknand_panic_write; ++ ++ mtd->_sync = rknand_sync; ++ mtd->_lock = NULL; ++ mtd->_unlock = NULL; ++ mtd->_suspend = NULL; ++ mtd->_resume = NULL; ++ mtd->_block_isbad = rknand_block_isbad; ++ mtd->_block_markbad = rknand_block_markbad; ++ mtd->owner = THIS_MODULE; ++ return 0; ++} ++ ++ ++/* ++ * CMY: ?????˶??????з?????Ï¢??Ö§?? ++ * ??cmdline???ṩ??????Ï¢????ʹ??cmdline?Ä·?????Ï¢???з??? ++ * ??cmdlineû???ṩ??????Ï¢????ʹ??Ĭ?ϵķ?????Ï¢(rk28_partition_info)???з??? ++ */ ++ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++const char *part_probes[] = { "cmdlinepart", NULL }; ++#endif ++ ++static int rknand_add_partitions(struct rknand_info *nand_info) ++{ ++#ifdef CONFIG_MTD_CMDLINE_PARTS ++ int num_partitions = 0; ++ ++ // ???????н???????????Ï¢ ++ num_partitions = parse_mtd_partitions(&(rknand_mtd), part_probes, &rknand_parts, 0); ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"num_partitions = %d\n",num_partitions); ++ printk("num_partitions = %d\n",num_partitions); ++ if(num_partitions > 0) { ++ int i; ++ for (i = 0; i < num_partitions; i++) ++ { ++ rknand_parts[i].offset *= 0x200; ++ rknand_parts[i].size *=0x200; ++ } ++ rknand_parts[num_partitions - 1].size = rknand_mtd.size - rknand_parts[num_partitions - 1].offset; ++ ++ g_num_partitions = num_partitions; ++//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) ++// return mtd_device_register(&rknand_mtd, rknand_parts, num_partitions); ++//#else ++ return add_mtd_partitions(&(rknand_mtd), rknand_parts, num_partitions); ++//#endif ++ } ++#endif ++ g_num_partitions = 0; ++ return 0; ++} ++ ++int add_rknand_device(struct rknand_info * prknand_Info) ++{ ++ struct mtd_partition *parts; ++ int i; ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"add_rknand_device: \n"); ++ printk("gpNandInfo->nandCapacity = %lx\n",gpNandInfo->nandCapacity); ++ rknand_mtd.size = (uint64_t)gpNandInfo->nandCapacity*0x200; ++ ++ rknand_add_partitions(prknand_Info); ++ ++ parts = rknand_parts; ++ SysImageWriteEndAdd = 0; ++ for(i=0;i>> part[%d]: name=%s offset=0x%012llx\n", i, parts[i].name, parts[i].offset); ++ if(strcmp(parts[i].name,"backup") == 0) ++ { ++ SysImageWriteEndAdd = (unsigned long)(parts[i].offset + parts[i].size)>>9;//sector ++ //printk(">>> SysImageWriteEndAdd=0x%lx\n", SysImageWriteEndAdd); ++ break; ++ } ++ } ++ if(SysImageWriteEndAdd) ++ gpNandInfo->SysImageWriteEndAdd = SysImageWriteEndAdd; ++ ++ //nandc_clk = clk_get(NULL, "nandc"); ++ //clk_enable(nandc_clk); ++ //rknand_nand_timing_cfg(); ++ ++ return 0; ++} ++ ++int get_rknand_device(struct rknand_info ** prknand_Info) ++{ ++ *prknand_Info = gpNandInfo; ++ return 0; ++} ++ ++EXPORT_SYMBOL(get_rknand_device); ++ ++int rknand_dma_map_single(unsigned long ptr,int size,int dir) ++{ ++ return dma_map_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE); ++} ++EXPORT_SYMBOL(rknand_dma_map_single); ++ ++void rknand_dma_unmap_single(unsigned long ptr,int size,int dir) ++{ ++ dma_unmap_single(NULL, ptr,size, dir?DMA_TO_DEVICE:DMA_FROM_DEVICE); ++} ++EXPORT_SYMBOL(rknand_dma_unmap_single); ++ ++int rknand_flash_cs_init(void) ++{ ++ ++} ++EXPORT_SYMBOL(rknand_flash_cs_init); ++ ++ ++int rknand_get_reg_addr(int *pNandc,int *pSDMMC0,int *pSDMMC1,int *pSDMMC2) ++{ ++ //*pNandc = ioremap(RK30_NANDC_PHYS,RK30_NANDC_SIZE); ++ //*pSDMMC0 = ioremap(SDMMC0_BASE_ADDR, 0x4000); ++ //*pSDMMC1 = ioremap(SDMMC1_BASE_ADDR, 0x4000); ++ //*pSDMMC2 = ioremap(EMMC_BASE_ADDR, 0x4000); ++ *pNandc = ioremap(0x10500000,0x4000); ++} ++EXPORT_SYMBOL(rknand_get_reg_addr); ++ ++static int g_nandc_irq = 27; ++int rknand_nandc_irq_init(int mode,void * pfun) ++{ ++ int ret = 0; ++ if(mode) //init ++ { ++ ret = request_irq(g_nandc_irq, pfun, 0, "nandc", NULL); ++ if(ret) ++ printk("request IRQ_NANDC irq , ret=%x.........\n", ret); ++ } ++ else //deinit ++ { ++ free_irq(g_nandc_irq, NULL); ++ } ++ return ret; ++} ++EXPORT_SYMBOL(rknand_nandc_irq_init); ++static int rknand_probe(struct platform_device *pdev) ++{ ++ struct rknand_info *nand_info; ++ int err = 0; ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rk_nand_probe: \n"); ++ gpNandInfo = kzalloc(sizeof(struct rknand_info), GFP_KERNEL); ++ if (!gpNandInfo) ++ return -ENOMEM; ++ ++ nand_info = gpNandInfo; ++ printk("rknand_probe: \n"); ++ ++ g_nandc_irq = platform_get_irq(pdev, 0); ++ if (g_nandc_irq < 0) { ++ dev_err(&pdev->dev, "no irq resource?\n"); ++ return g_nandc_irq; ++ } ++ ++ memset(gpNandInfo,0,sizeof(struct rknand_info)); ++ ++ gpNandInfo->bufSize = MAX_BUFFER_SIZE * 512; ++ gpNandInfo->pbuf = (char *)NULL;//grknand_buf; ++ gpNandInfo->pdmaBuf = (char *)NULL;//grknand_dma_buf; ++ //printk(" gpNandInfo->pdmaBuf=0x%x\n", gpNandInfo->pdmaBuf); ++#ifdef CONFIG_MTD_EMMC_CLK_POWER_SAVE ++ gpNandInfo->emmc_clk_power_save_en = 1; ++#endif ++ ++ rknand_mtd.name = DRIVER_NAME;//dev_name(&pdev->dev); ++ rknand_mtd.priv = &nand_info->rknand; ++ rknand_mtd.owner = THIS_MODULE; ++ ++ if(rknand_info_init(nand_info)) ++ { ++ err = -ENXIO; ++ goto exit_free; ++ } ++ ++ nand_info->add_rknand_device = add_rknand_device; ++ nand_info->get_rknand_device = get_rknand_device; ++ ++ rknand_create_procfs(); ++ return 0; ++ ++exit_free: ++ if(nand_info) ++ kfree(nand_info); ++ ++ return err; ++} ++ ++static int rknand_suspend(struct platform_device *pdev, pm_message_t state) ++{ ++ gpNandInfo->rknand.rknand_schedule_enable = 0; ++ // if(gpNandInfo->rknand_suspend) ++ // gpNandInfo->rknand_suspend(); ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_suspend: \n"); ++ return 0; ++} ++ ++static int rknand_resume(struct platform_device *pdev) ++{ ++ //if(gpNandInfo->rknand_resume) ++ // gpNandInfo->rknand_resume(); ++ gpNandInfo->rknand.rknand_schedule_enable = 1; ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_resume: \n"); ++ return 0; ++} ++ ++void rknand_shutdown(struct platform_device *pdev) ++{ ++ printk("rknand_shutdown...\n"); ++ gpNandInfo->rknand.rknand_schedule_enable = 0; ++ if(gpNandInfo->rknand_buffer_shutdown) ++ gpNandInfo->rknand_buffer_shutdown(); ++} ++ ++#ifdef CONFIG_OF ++static const struct of_device_id of_rk_nandc_match[] = { ++ { .compatible = "rockchip,rk-nandc" }, ++ { /* Sentinel */ } ++}; ++#endif ++ ++static struct platform_driver rknand_driver = { ++ .probe = rknand_probe, ++ .suspend = rknand_suspend, ++ .resume = rknand_resume, ++ .shutdown = rknand_shutdown, ++ .driver = { ++ .name = DRIVER_NAME, ++#ifdef CONFIG_OF ++ .of_match_table = of_rk_nandc_match, ++#endif ++ .owner = THIS_MODULE, ++ }, ++}; ++ ++ ++MODULE_ALIAS(DRIVER_NAME); ++ ++static int __init rknand_init(void) ++{ ++ int ret; ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"rknand_init: \n"); ++ ret = platform_driver_register(&rknand_driver); ++ NAND_DEBUG(NAND_DEBUG_LEVEL0,"platform_driver_register:ret = %x \n",ret); ++ return ret; ++} ++ ++static void __exit rknand_exit(void) ++{ ++ platform_driver_unregister(&rknand_driver); ++} ++ ++module_init(rknand_init); ++module_exit(rknand_exit); ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("ZYF "); ++MODULE_DESCRIPTION("rknand driver."); ++ ++ diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index f8cde9f9f..5d7ace2e5 100644 --- a/drivers/net/can/Kconfig @@ -1839027,206 +1839027,206 @@ index 000000000..947a9b925 +++ b/drivers/video/rockchip/rga/RGA_API.c @@ -0,0 +1,201 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+ -+#include -+#include "RGA_API.h" -+#include "rga.h" -+//#include "rga_angle.h" -+ -+#define IS_YUV_420(format) \ -+ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ -+ (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP)) -+ -+#define IS_YUV_422(format) \ -+ ((format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ -+ (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) -+ -+#define IS_YUV(format) \ -+ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ -+ (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP) | \ -+ (format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ -+ (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) -+ -+ -+extern rga_service_info rga_service; -+ -+ -+void -+matrix_cal(const struct rga_req *msg, TILE_INFO *tile) -+{ -+ uint64_t x_time, y_time; -+ uint64_t sina, cosa; -+ -+ int s_act_w, s_act_h, d_act_w, d_act_h; -+ -+ s_act_w = msg->src.act_w; -+ s_act_h = msg->src.act_h; -+ d_act_w = msg->dst.act_w; -+ d_act_h = msg->dst.act_h; -+ -+ if (s_act_w == 1) s_act_w += 1; -+ if (s_act_h == 1) s_act_h += 1; -+ if (d_act_h == 1) d_act_h += 1; -+ if (d_act_w == 1) d_act_w += 1; -+ -+ x_time = ((s_act_w - 1)<<16) / (d_act_w - 1); -+ y_time = ((s_act_h - 1)<<16) / (d_act_h - 1); -+ -+ sina = msg->sina; -+ cosa = msg->cosa; -+ -+ switch(msg->rotate_mode) -+ { -+ /* 16.16 x 16.16 */ -+ /* matrix[] is 64 bit wide */ -+ case 1 : -+ tile->matrix[0] = cosa*x_time; -+ tile->matrix[1] = -sina*y_time; -+ tile->matrix[2] = sina*x_time; -+ tile->matrix[3] = cosa*y_time; -+ break; -+ case 2 : -+ tile->matrix[0] = -(x_time<<16); -+ tile->matrix[1] = 0; -+ tile->matrix[2] = 0; -+ tile->matrix[3] = (y_time<<16); -+ break; -+ case 3 : -+ tile->matrix[0] = (x_time<<16); -+ tile->matrix[1] = 0; -+ tile->matrix[2] = 0; -+ tile->matrix[3] = -(y_time<<16); -+ break; -+ default : -+ tile->matrix[0] = (uint64_t)1<<32; -+ tile->matrix[1] = 0; -+ tile->matrix[2] = 0; -+ tile->matrix[3] = (uint64_t)1<<32; -+ break; -+ } -+} -+ -+ -+int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) -+{ -+ -+ struct rga_req *mp; -+ uint32_t w_ratio, h_ratio; -+ uint32_t stride; -+ -+ uint32_t daw, dah; -+ uint32_t pl; -+ -+ daw = dah = 0; -+ -+ mp = msg1; -+ -+ if(msg->dst.act_w == 0) -+ { -+ printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__); -+ return -EINVAL; -+ } -+ -+ if (msg->dst.act_h == 0) -+ { -+ printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__); -+ return -EINVAL; -+ } -+ w_ratio = (msg->src.act_w << 16) / msg->dst.act_w; -+ h_ratio = (msg->src.act_h << 16) / msg->dst.act_h; -+ -+ memcpy(msg1, msg, sizeof(struct rga_req)); -+ -+ msg->dst.format = msg->src.format; -+ -+ /*pre_scale_w cal*/ -+ if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) { -+ daw = (msg->src.act_w + 1) >> 1; -+ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { -+ daw -= 1; -+ msg->src.act_w = daw << 1; -+ } -+ } -+ else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) { -+ daw = (msg->src.act_w + 3) >> 2; -+ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { -+ daw -= 1; -+ msg->src.act_w = daw << 2; -+ } -+ } -+ else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) { -+ daw = (msg->src.act_w + 7) >> 3; -+ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { -+ daw -= 1; -+ msg->src.act_w = daw << 3; -+ } -+ } -+ else -+ { -+ daw = msg->src.act_w; -+ } -+ -+ pl = (RGA_pixel_width_init(msg->src.format)); -+ stride = (pl * daw + 3) & (~3); -+ msg->dst.act_w = daw; -+ msg->dst.vir_w = stride / pl; -+ -+ /*pre_scale_h cal*/ -+ if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) { -+ dah = (msg->src.act_h + 1) >> 1; -+ if((IS_YUV(msg->dst.format)) && (dah & 1)) { -+ dah -= 1; -+ msg->src.act_h = dah << 1; -+ } -+ } -+ else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) { -+ dah = (msg->src.act_h + 3) >> 2; -+ if((IS_YUV(msg->dst.format)) && (dah & 1)) { -+ dah -= 1; -+ msg->src.act_h = dah << 2; -+ -+ } -+ } -+ else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) { -+ dah = (msg->src.act_h + 7) >> 3; -+ if((IS_YUV(msg->dst.format)) && (dah & 1)) { -+ dah -= 1; -+ msg->src.act_h = dah << 3; -+ } -+ } -+ else -+ { -+ dah = msg->src.act_h; -+ } -+ -+ msg->dst.act_h = dah; -+ msg->dst.vir_h = dah; -+ -+ msg->dst.x_offset = 0; -+ msg->dst.y_offset = 0; -+ -+ msg->dst.yrgb_addr = (unsigned long)rga_service.pre_scale_buf; -+ msg->dst.uv_addr = msg->dst.yrgb_addr + stride * dah; -+ msg->dst.v_addr = msg->dst.uv_addr + ((stride * dah) >> 1); -+ -+ msg->render_mode = pre_scaling_mode; -+ -+ msg1->src.yrgb_addr = msg->dst.yrgb_addr; -+ msg1->src.uv_addr = msg->dst.uv_addr; -+ msg1->src.v_addr = msg->dst.v_addr; -+ -+ msg1->src.act_w = msg->dst.act_w; -+ msg1->src.act_h = msg->dst.act_h; -+ msg1->src.vir_w = msg->dst.vir_w; -+ msg1->src.vir_h = msg->dst.vir_h; -+ -+ msg1->src.x_offset = 0; -+ msg1->src.y_offset = 0; -+ -+ return 0; -+} -+ -+ ++ ++#include ++#include "RGA_API.h" ++#include "rga.h" ++//#include "rga_angle.h" ++ ++#define IS_YUV_420(format) \ ++ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ ++ (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP)) ++ ++#define IS_YUV_422(format) \ ++ ((format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ ++ (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) ++ ++#define IS_YUV(format) \ ++ ((format == RK_FORMAT_YCbCr_420_P) | (format == RK_FORMAT_YCbCr_420_SP) | \ ++ (format == RK_FORMAT_YCrCb_420_P) | (format == RK_FORMAT_YCrCb_420_SP) | \ ++ (format == RK_FORMAT_YCbCr_422_P) | (format == RK_FORMAT_YCbCr_422_SP) | \ ++ (format == RK_FORMAT_YCrCb_422_P) | (format == RK_FORMAT_YCrCb_422_SP)) ++ ++ ++extern rga_service_info rga_service; ++ ++ ++void ++matrix_cal(const struct rga_req *msg, TILE_INFO *tile) ++{ ++ uint64_t x_time, y_time; ++ uint64_t sina, cosa; ++ ++ int s_act_w, s_act_h, d_act_w, d_act_h; ++ ++ s_act_w = msg->src.act_w; ++ s_act_h = msg->src.act_h; ++ d_act_w = msg->dst.act_w; ++ d_act_h = msg->dst.act_h; ++ ++ if (s_act_w == 1) s_act_w += 1; ++ if (s_act_h == 1) s_act_h += 1; ++ if (d_act_h == 1) d_act_h += 1; ++ if (d_act_w == 1) d_act_w += 1; ++ ++ x_time = ((s_act_w - 1)<<16) / (d_act_w - 1); ++ y_time = ((s_act_h - 1)<<16) / (d_act_h - 1); ++ ++ sina = msg->sina; ++ cosa = msg->cosa; ++ ++ switch(msg->rotate_mode) ++ { ++ /* 16.16 x 16.16 */ ++ /* matrix[] is 64 bit wide */ ++ case 1 : ++ tile->matrix[0] = cosa*x_time; ++ tile->matrix[1] = -sina*y_time; ++ tile->matrix[2] = sina*x_time; ++ tile->matrix[3] = cosa*y_time; ++ break; ++ case 2 : ++ tile->matrix[0] = -(x_time<<16); ++ tile->matrix[1] = 0; ++ tile->matrix[2] = 0; ++ tile->matrix[3] = (y_time<<16); ++ break; ++ case 3 : ++ tile->matrix[0] = (x_time<<16); ++ tile->matrix[1] = 0; ++ tile->matrix[2] = 0; ++ tile->matrix[3] = -(y_time<<16); ++ break; ++ default : ++ tile->matrix[0] = (uint64_t)1<<32; ++ tile->matrix[1] = 0; ++ tile->matrix[2] = 0; ++ tile->matrix[3] = (uint64_t)1<<32; ++ break; ++ } ++} ++ ++ ++int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1) ++{ ++ ++ struct rga_req *mp; ++ uint32_t w_ratio, h_ratio; ++ uint32_t stride; ++ ++ uint32_t daw, dah; ++ uint32_t pl; ++ ++ daw = dah = 0; ++ ++ mp = msg1; ++ ++ if(msg->dst.act_w == 0) ++ { ++ printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__); ++ return -EINVAL; ++ } ++ ++ if (msg->dst.act_h == 0) ++ { ++ printk("%s, [%d] rga dst act_w is zero\n", __FUNCTION__, __LINE__); ++ return -EINVAL; ++ } ++ w_ratio = (msg->src.act_w << 16) / msg->dst.act_w; ++ h_ratio = (msg->src.act_h << 16) / msg->dst.act_h; ++ ++ memcpy(msg1, msg, sizeof(struct rga_req)); ++ ++ msg->dst.format = msg->src.format; ++ ++ /*pre_scale_w cal*/ ++ if ((w_ratio >= (2<<16)) && (w_ratio < (4<<16))) { ++ daw = (msg->src.act_w + 1) >> 1; ++ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { ++ daw -= 1; ++ msg->src.act_w = daw << 1; ++ } ++ } ++ else if ((w_ratio >= (4<<16)) && (w_ratio < (8<<16))) { ++ daw = (msg->src.act_w + 3) >> 2; ++ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { ++ daw -= 1; ++ msg->src.act_w = daw << 2; ++ } ++ } ++ else if ((w_ratio >= (8<<16)) && (w_ratio < (16<<16))) { ++ daw = (msg->src.act_w + 7) >> 3; ++ if((IS_YUV_420(msg->dst.format)) && (daw & 1)) { ++ daw -= 1; ++ msg->src.act_w = daw << 3; ++ } ++ } ++ else ++ { ++ daw = msg->src.act_w; ++ } ++ ++ pl = (RGA_pixel_width_init(msg->src.format)); ++ stride = (pl * daw + 3) & (~3); ++ msg->dst.act_w = daw; ++ msg->dst.vir_w = stride / pl; ++ ++ /*pre_scale_h cal*/ ++ if ((h_ratio >= (2<<16)) && (h_ratio < (4<<16))) { ++ dah = (msg->src.act_h + 1) >> 1; ++ if((IS_YUV(msg->dst.format)) && (dah & 1)) { ++ dah -= 1; ++ msg->src.act_h = dah << 1; ++ } ++ } ++ else if ((h_ratio >= (4<<16)) && (h_ratio < (8<<16))) { ++ dah = (msg->src.act_h + 3) >> 2; ++ if((IS_YUV(msg->dst.format)) && (dah & 1)) { ++ dah -= 1; ++ msg->src.act_h = dah << 2; ++ ++ } ++ } ++ else if ((h_ratio >= (8<<16)) && (h_ratio < (16<<16))) { ++ dah = (msg->src.act_h + 7) >> 3; ++ if((IS_YUV(msg->dst.format)) && (dah & 1)) { ++ dah -= 1; ++ msg->src.act_h = dah << 3; ++ } ++ } ++ else ++ { ++ dah = msg->src.act_h; ++ } ++ ++ msg->dst.act_h = dah; ++ msg->dst.vir_h = dah; ++ ++ msg->dst.x_offset = 0; ++ msg->dst.y_offset = 0; ++ ++ msg->dst.yrgb_addr = (unsigned long)rga_service.pre_scale_buf; ++ msg->dst.uv_addr = msg->dst.yrgb_addr + stride * dah; ++ msg->dst.v_addr = msg->dst.uv_addr + ((stride * dah) >> 1); ++ ++ msg->render_mode = pre_scaling_mode; ++ ++ msg1->src.yrgb_addr = msg->dst.yrgb_addr; ++ msg1->src.uv_addr = msg->dst.uv_addr; ++ msg1->src.v_addr = msg->dst.v_addr; ++ ++ msg1->src.act_w = msg->dst.act_w; ++ msg1->src.act_h = msg->dst.act_h; ++ msg1->src.vir_w = msg->dst.vir_w; ++ msg1->src.vir_h = msg->dst.vir_h; ++ ++ msg1->src.x_offset = 0; ++ msg1->src.y_offset = 0; ++ ++ return 0; ++} ++ ++ diff --git a/drivers/video/rockchip/rga/RGA_API.h b/drivers/video/rockchip/rga/RGA_API.h new file mode 100644 index 000000000..ade17d03e @@ -1839234,16 +1839234,16 @@ index 000000000..ade17d03e +++ b/drivers/video/rockchip/rga/RGA_API.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __RGA_API_H__ -+#define __RGA_API_H__ ++#ifndef __RGA_API_H__ ++#define __RGA_API_H__ + +#include +#include -+ -+#include "rga_reg_info.h" -+#include "rga.h" -+ -+#define ENABLE 1 ++ ++#include "rga_reg_info.h" ++#include "rga.h" ++ ++#define ENABLE 1 +#define DISABLE 0 + +struct rga_drvdata { @@ -1839266,13 +1839266,13 @@ index 000000000..ade17d03e + char *version; +}; + -+int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1); -+ -+ -+ -+ -+ -+#endif ++int32_t RGA_gen_two_pro(struct rga_req *msg, struct rga_req *msg1); ++ ++ ++ ++ ++ ++#endif diff --git a/drivers/video/rockchip/rga/rga.h b/drivers/video/rockchip/rga/rga.h new file mode 100644 index 000000000..59da2042a @@ -1839280,562 +1839280,562 @@ index 000000000..59da2042a +++ b/drivers/video/rockchip/rga/rga.h @@ -0,0 +1,507 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef _RGA_DRIVER_H_ -+#define _RGA_DRIVER_H_ -+ -+#include -+#include -+ -+ -+#define RGA_BLIT_SYNC 0x5017 -+#define RGA_BLIT_ASYNC 0x5018 -+#define RGA_FLUSH 0x5019 -+#define RGA_GET_RESULT 0x501a -+#define RGA_GET_VERSION 0x501b -+ -+ -+#define RGA_REG_CTRL_LEN 0x8 /* 8 */ -+#define RGA_REG_CMD_LEN 0x20 /* 32 */ -+#define RGA_CMD_BUF_SIZE 0x700 /* 16*28*4 */ -+ -+#define RGA_OUT_OF_RESOURCES -10 -+#define RGA_MALLOC_ERROR -11 -+ ++#ifndef _RGA_DRIVER_H_ ++#define _RGA_DRIVER_H_ ++ ++#include ++#include ++ ++ ++#define RGA_BLIT_SYNC 0x5017 ++#define RGA_BLIT_ASYNC 0x5018 ++#define RGA_FLUSH 0x5019 ++#define RGA_GET_RESULT 0x501a ++#define RGA_GET_VERSION 0x501b ++ ++ ++#define RGA_REG_CTRL_LEN 0x8 /* 8 */ ++#define RGA_REG_CMD_LEN 0x20 /* 32 */ ++#define RGA_CMD_BUF_SIZE 0x700 /* 16*28*4 */ ++ ++#define RGA_OUT_OF_RESOURCES -10 ++#define RGA_MALLOC_ERROR -11 ++ +#define RGA_BUF_GEM_TYPE_MASK 0xC0 -+ -+#define rgaIS_ERROR(status) (status < 0) -+#define rgaNO_ERROR(status) (status >= 0) -+#define rgaIS_SUCCESS(status) (status == 0) -+ ++ ++#define rgaIS_ERROR(status) (status < 0) ++#define rgaNO_ERROR(status) (status >= 0) ++#define rgaIS_SUCCESS(status) (status == 0) ++ +#define RGA_DEBUGFS 1 -+ -+/* RGA process mode enum */ -+enum -+{ -+ bitblt_mode = 0x0, -+ color_palette_mode = 0x1, -+ color_fill_mode = 0x2, -+ line_point_drawing_mode = 0x3, -+ blur_sharp_filter_mode = 0x4, -+ pre_scaling_mode = 0x5, -+ update_palette_table_mode = 0x6, -+ update_patten_buff_mode = 0x7, -+}; -+ -+ -+enum -+{ -+ rop_enable_mask = 0x2, -+ dither_enable_mask = 0x8, -+ fading_enable_mask = 0x10, -+ PD_enbale_mask = 0x20, -+}; -+ -+enum -+{ -+ yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */ -+ yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */ -+ yuv2rgb_mode2 = 0x2, /* BT.709 */ -+}; -+ -+ -+/* RGA rotate mode */ -+enum -+{ -+ rotate_mode0 = 0x0, /* no rotate */ -+ rotate_mode1 = 0x1, /* rotate */ -+ rotate_mode2 = 0x2, /* x_mirror */ -+ rotate_mode3 = 0x3, /* y_mirror */ -+}; -+ -+enum -+{ -+ color_palette_mode0 = 0x0, /* 1K */ -+ color_palette_mode1 = 0x1, /* 2K */ -+ color_palette_mode2 = 0x2, /* 4K */ -+ color_palette_mode3 = 0x3, /* 8K */ -+}; -+ -+ -+ -+/* -+// Alpha Red Green Blue -+{ 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // RK_FORMAT_RGBA_8888 -+{ 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGBX_8888 -+{ 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGB_888 -+{ 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_BGRA }, // RK_FORMAT_BGRA_8888 -+{ 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // RK_FORMAT_RGB_565 -+{ 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // RK_FORMAT_RGBA_5551 -+{ 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // RK_FORMAT_RGBA_4444 -+{ 3, 24, {{ 0, 0, 24,16, 16, 8, 8, 0 }}, GGL_BGR }, // RK_FORMAT_BGB_888 -+ -+*/ -+enum -+{ -+ RK_FORMAT_RGBA_8888 = 0x0, -+ RK_FORMAT_RGBX_8888 = 0x1, -+ RK_FORMAT_RGB_888 = 0x2, -+ RK_FORMAT_BGRA_8888 = 0x3, -+ RK_FORMAT_RGB_565 = 0x4, -+ RK_FORMAT_RGBA_5551 = 0x5, -+ RK_FORMAT_RGBA_4444 = 0x6, -+ RK_FORMAT_BGR_888 = 0x7, -+ -+ RK_FORMAT_YCbCr_422_SP = 0x8, -+ RK_FORMAT_YCbCr_422_P = 0x9, -+ RK_FORMAT_YCbCr_420_SP = 0xa, -+ RK_FORMAT_YCbCr_420_P = 0xb, -+ -+ RK_FORMAT_YCrCb_422_SP = 0xc, -+ RK_FORMAT_YCrCb_422_P = 0xd, -+ RK_FORMAT_YCrCb_420_SP = 0xe, -+ RK_FORMAT_YCrCb_420_P = 0xf, -+ -+ RK_FORMAT_BPP1 = 0x10, -+ RK_FORMAT_BPP2 = 0x11, -+ RK_FORMAT_BPP4 = 0x12, -+ RK_FORMAT_BPP8 = 0x13, -+ RK_FORMAT_YCbCr_420_SP_10B = 0x20, -+ RK_FORMAT_YCrCb_420_SP_10B = 0x21, -+}; -+ -+ -+typedef struct rga_img_info_t -+{ -+ unsigned long yrgb_addr; /* yrgb mem addr */ -+ unsigned long uv_addr; /* cb/cr mem addr */ -+ unsigned long v_addr; /* cr mem addr */ -+ unsigned int format; //definition by RK_FORMAT -+ -+ unsigned short act_w; -+ unsigned short act_h; -+ unsigned short x_offset; -+ unsigned short y_offset; -+ -+ unsigned short vir_w; -+ unsigned short vir_h; -+ -+ unsigned short endian_mode; //for BPP -+ unsigned short alpha_swap; -+} -+rga_img_info_t; -+ -+ -+typedef struct mdp_img_act -+{ -+ unsigned short w; // width -+ unsigned short h; // height -+ short x_off; // x offset for the vir -+ short y_off; // y offset for the vir -+} -+mdp_img_act; -+ -+ -+ -+typedef struct RANGE -+{ -+ unsigned short min; -+ unsigned short max; -+} -+RANGE; -+ -+typedef struct POINT -+{ -+ unsigned short x; -+ unsigned short y; -+} -+POINT; -+ -+typedef struct RECT -+{ -+ unsigned short xmin; -+ unsigned short xmax; // width - 1 -+ unsigned short ymin; -+ unsigned short ymax; // height - 1 -+} RECT; -+ -+typedef struct RGB -+{ -+ unsigned char r; -+ unsigned char g; -+ unsigned char b; -+ unsigned char res; -+}RGB; -+ -+ -+typedef struct MMU -+{ -+ unsigned char mmu_en; -+ unsigned long base_addr; ++ ++/* RGA process mode enum */ ++enum ++{ ++ bitblt_mode = 0x0, ++ color_palette_mode = 0x1, ++ color_fill_mode = 0x2, ++ line_point_drawing_mode = 0x3, ++ blur_sharp_filter_mode = 0x4, ++ pre_scaling_mode = 0x5, ++ update_palette_table_mode = 0x6, ++ update_patten_buff_mode = 0x7, ++}; ++ ++ ++enum ++{ ++ rop_enable_mask = 0x2, ++ dither_enable_mask = 0x8, ++ fading_enable_mask = 0x10, ++ PD_enbale_mask = 0x20, ++}; ++ ++enum ++{ ++ yuv2rgb_mode0 = 0x0, /* BT.601 MPEG */ ++ yuv2rgb_mode1 = 0x1, /* BT.601 JPEG */ ++ yuv2rgb_mode2 = 0x2, /* BT.709 */ ++}; ++ ++ ++/* RGA rotate mode */ ++enum ++{ ++ rotate_mode0 = 0x0, /* no rotate */ ++ rotate_mode1 = 0x1, /* rotate */ ++ rotate_mode2 = 0x2, /* x_mirror */ ++ rotate_mode3 = 0x3, /* y_mirror */ ++}; ++ ++enum ++{ ++ color_palette_mode0 = 0x0, /* 1K */ ++ color_palette_mode1 = 0x1, /* 2K */ ++ color_palette_mode2 = 0x2, /* 4K */ ++ color_palette_mode3 = 0x3, /* 8K */ ++}; ++ ++ ++ ++/* ++// Alpha Red Green Blue ++{ 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // RK_FORMAT_RGBA_8888 ++{ 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGBX_8888 ++{ 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // RK_FORMAT_RGB_888 ++{ 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_BGRA }, // RK_FORMAT_BGRA_8888 ++{ 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // RK_FORMAT_RGB_565 ++{ 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // RK_FORMAT_RGBA_5551 ++{ 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // RK_FORMAT_RGBA_4444 ++{ 3, 24, {{ 0, 0, 24,16, 16, 8, 8, 0 }}, GGL_BGR }, // RK_FORMAT_BGB_888 ++ ++*/ ++enum ++{ ++ RK_FORMAT_RGBA_8888 = 0x0, ++ RK_FORMAT_RGBX_8888 = 0x1, ++ RK_FORMAT_RGB_888 = 0x2, ++ RK_FORMAT_BGRA_8888 = 0x3, ++ RK_FORMAT_RGB_565 = 0x4, ++ RK_FORMAT_RGBA_5551 = 0x5, ++ RK_FORMAT_RGBA_4444 = 0x6, ++ RK_FORMAT_BGR_888 = 0x7, ++ ++ RK_FORMAT_YCbCr_422_SP = 0x8, ++ RK_FORMAT_YCbCr_422_P = 0x9, ++ RK_FORMAT_YCbCr_420_SP = 0xa, ++ RK_FORMAT_YCbCr_420_P = 0xb, ++ ++ RK_FORMAT_YCrCb_422_SP = 0xc, ++ RK_FORMAT_YCrCb_422_P = 0xd, ++ RK_FORMAT_YCrCb_420_SP = 0xe, ++ RK_FORMAT_YCrCb_420_P = 0xf, ++ ++ RK_FORMAT_BPP1 = 0x10, ++ RK_FORMAT_BPP2 = 0x11, ++ RK_FORMAT_BPP4 = 0x12, ++ RK_FORMAT_BPP8 = 0x13, ++ RK_FORMAT_YCbCr_420_SP_10B = 0x20, ++ RK_FORMAT_YCrCb_420_SP_10B = 0x21, ++}; ++ ++ ++typedef struct rga_img_info_t ++{ ++ unsigned long yrgb_addr; /* yrgb mem addr */ ++ unsigned long uv_addr; /* cb/cr mem addr */ ++ unsigned long v_addr; /* cr mem addr */ ++ unsigned int format; //definition by RK_FORMAT ++ ++ unsigned short act_w; ++ unsigned short act_h; ++ unsigned short x_offset; ++ unsigned short y_offset; ++ ++ unsigned short vir_w; ++ unsigned short vir_h; ++ ++ unsigned short endian_mode; //for BPP ++ unsigned short alpha_swap; ++} ++rga_img_info_t; ++ ++ ++typedef struct mdp_img_act ++{ ++ unsigned short w; // width ++ unsigned short h; // height ++ short x_off; // x offset for the vir ++ short y_off; // y offset for the vir ++} ++mdp_img_act; ++ ++ ++ ++typedef struct RANGE ++{ ++ unsigned short min; ++ unsigned short max; ++} ++RANGE; ++ ++typedef struct POINT ++{ ++ unsigned short x; ++ unsigned short y; ++} ++POINT; ++ ++typedef struct RECT ++{ ++ unsigned short xmin; ++ unsigned short xmax; // width - 1 ++ unsigned short ymin; ++ unsigned short ymax; // height - 1 ++} RECT; ++ ++typedef struct RGB ++{ ++ unsigned char r; ++ unsigned char g; ++ unsigned char b; ++ unsigned char res; ++}RGB; ++ ++ ++typedef struct MMU ++{ ++ unsigned char mmu_en; ++ unsigned long base_addr; + uint32_t mmu_flag; -+} MMU; -+ -+ -+ -+ -+typedef struct COLOR_FILL -+{ -+ short gr_x_a; -+ short gr_y_a; -+ short gr_x_b; -+ short gr_y_b; -+ short gr_x_g; -+ short gr_y_g; -+ short gr_x_r; -+ short gr_y_r; -+ -+ //u8 cp_gr_saturation; -+} -+COLOR_FILL; -+ -+typedef struct FADING -+{ -+ uint8_t b; -+ uint8_t g; -+ uint8_t r; -+ uint8_t res; -+} -+FADING; -+ -+ -+typedef struct line_draw_t -+{ -+ POINT start_point; /* LineDraw_start_point */ -+ POINT end_point; /* LineDraw_end_point */ -+ uint32_t color; /* LineDraw_color */ -+ uint32_t flag; /* (enum) LineDrawing mode sel */ -+ uint32_t line_width; /* range 1~16 */ -+} -+line_draw_t; -+ -+ -+ -+struct rga_req { -+ uint8_t render_mode; /* (enum) process mode sel */ -+ -+ rga_img_info_t src; /* src image info */ -+ rga_img_info_t dst; /* dst image info */ -+ rga_img_info_t pat; /* patten image info */ -+ -+ unsigned long rop_mask_addr; /* rop4 mask addr */ -+ unsigned long LUT_addr; /* LUT addr */ -+ -+ RECT clip; /* dst clip window default value is dst_vir */ -+ /* value from [0, w-1] / [0, h-1]*/ -+ -+ int32_t sina; /* dst angle default value 0 16.16 scan from table */ -+ int32_t cosa; /* dst angle default value 0 16.16 scan from table */ -+ -+ uint16_t alpha_rop_flag; /* alpha rop process flag */ -+ /* ([0] = 1 alpha_rop_enable) */ -+ /* ([1] = 1 rop enable) */ -+ /* ([2] = 1 fading_enable) */ -+ /* ([3] = 1 PD_enable) */ -+ /* ([4] = 1 alpha cal_mode_sel) */ -+ /* ([5] = 1 dither_enable) */ -+ /* ([6] = 1 gradient fill mode sel) */ -+ /* ([7] = 1 AA_enable) */ -+ -+ uint8_t scale_mode; /* 0 nearst / 1 bilnear / 2 bicubic */ -+ -+ uint32_t color_key_max; /* color key max */ -+ uint32_t color_key_min; /* color key min */ -+ -+ uint32_t fg_color; /* foreground color */ -+ uint32_t bg_color; /* background color */ -+ -+ COLOR_FILL gr_color; /* color fill use gradient */ -+ -+ line_draw_t line_draw_info; -+ -+ FADING fading; -+ -+ uint8_t PD_mode; /* porter duff alpha mode sel */ -+ -+ uint8_t alpha_global_value; /* global alpha value */ -+ -+ uint16_t rop_code; /* rop2/3/4 code scan from rop code table*/ -+ -+ uint8_t bsfilter_flag; /* [2] 0 blur 1 sharp / [1:0] filter_type*/ -+ -+ uint8_t palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/ -+ -+ uint8_t yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */ -+ -+ uint8_t endian_mode; /* 0/big endian 1/little endian*/ -+ -+ uint8_t rotate_mode; /* (enum) rotate mode */ -+ /* 0x0, no rotate */ -+ /* 0x1, rotate */ -+ /* 0x2, x_mirror */ -+ /* 0x3, y_mirror */ -+ -+ uint8_t color_fill_mode; /* 0 solid color / 1 patten color */ -+ -+ MMU mmu_info; /* mmu information */ -+ -+ uint8_t alpha_rop_mode; /* ([0~1] alpha mode) */ -+ /* ([2~3] rop mode) */ -+ /* ([4] zero mode en) */ -+ /* ([5] dst alpha mode) */ -+ -+ uint8_t src_trans_mode; -+ -+ struct sg_table *sg_src; ++} MMU; ++ ++ ++ ++ ++typedef struct COLOR_FILL ++{ ++ short gr_x_a; ++ short gr_y_a; ++ short gr_x_b; ++ short gr_y_b; ++ short gr_x_g; ++ short gr_y_g; ++ short gr_x_r; ++ short gr_y_r; ++ ++ //u8 cp_gr_saturation; ++} ++COLOR_FILL; ++ ++typedef struct FADING ++{ ++ uint8_t b; ++ uint8_t g; ++ uint8_t r; ++ uint8_t res; ++} ++FADING; ++ ++ ++typedef struct line_draw_t ++{ ++ POINT start_point; /* LineDraw_start_point */ ++ POINT end_point; /* LineDraw_end_point */ ++ uint32_t color; /* LineDraw_color */ ++ uint32_t flag; /* (enum) LineDrawing mode sel */ ++ uint32_t line_width; /* range 1~16 */ ++} ++line_draw_t; ++ ++ ++ ++struct rga_req { ++ uint8_t render_mode; /* (enum) process mode sel */ ++ ++ rga_img_info_t src; /* src image info */ ++ rga_img_info_t dst; /* dst image info */ ++ rga_img_info_t pat; /* patten image info */ ++ ++ unsigned long rop_mask_addr; /* rop4 mask addr */ ++ unsigned long LUT_addr; /* LUT addr */ ++ ++ RECT clip; /* dst clip window default value is dst_vir */ ++ /* value from [0, w-1] / [0, h-1]*/ ++ ++ int32_t sina; /* dst angle default value 0 16.16 scan from table */ ++ int32_t cosa; /* dst angle default value 0 16.16 scan from table */ ++ ++ uint16_t alpha_rop_flag; /* alpha rop process flag */ ++ /* ([0] = 1 alpha_rop_enable) */ ++ /* ([1] = 1 rop enable) */ ++ /* ([2] = 1 fading_enable) */ ++ /* ([3] = 1 PD_enable) */ ++ /* ([4] = 1 alpha cal_mode_sel) */ ++ /* ([5] = 1 dither_enable) */ ++ /* ([6] = 1 gradient fill mode sel) */ ++ /* ([7] = 1 AA_enable) */ ++ ++ uint8_t scale_mode; /* 0 nearst / 1 bilnear / 2 bicubic */ ++ ++ uint32_t color_key_max; /* color key max */ ++ uint32_t color_key_min; /* color key min */ ++ ++ uint32_t fg_color; /* foreground color */ ++ uint32_t bg_color; /* background color */ ++ ++ COLOR_FILL gr_color; /* color fill use gradient */ ++ ++ line_draw_t line_draw_info; ++ ++ FADING fading; ++ ++ uint8_t PD_mode; /* porter duff alpha mode sel */ ++ ++ uint8_t alpha_global_value; /* global alpha value */ ++ ++ uint16_t rop_code; /* rop2/3/4 code scan from rop code table*/ ++ ++ uint8_t bsfilter_flag; /* [2] 0 blur 1 sharp / [1:0] filter_type*/ ++ ++ uint8_t palette_mode; /* (enum) color palatte 0/1bpp, 1/2bpp 2/4bpp 3/8bpp*/ ++ ++ uint8_t yuv2rgb_mode; /* (enum) BT.601 MPEG / BT.601 JPEG / BT.709 */ ++ ++ uint8_t endian_mode; /* 0/big endian 1/little endian*/ ++ ++ uint8_t rotate_mode; /* (enum) rotate mode */ ++ /* 0x0, no rotate */ ++ /* 0x1, rotate */ ++ /* 0x2, x_mirror */ ++ /* 0x3, y_mirror */ ++ ++ uint8_t color_fill_mode; /* 0 solid color / 1 patten color */ ++ ++ MMU mmu_info; /* mmu information */ ++ ++ uint8_t alpha_rop_mode; /* ([0~1] alpha mode) */ ++ /* ([2~3] rop mode) */ ++ /* ([4] zero mode en) */ ++ /* ([5] dst alpha mode) */ ++ ++ uint8_t src_trans_mode; ++ ++ struct sg_table *sg_src; + struct sg_table *sg_dst; + struct dma_buf_attachment *attach_src; + struct dma_buf_attachment *attach_dst; -+}; -+ -+ -+typedef struct TILE_INFO -+{ -+ int64_t matrix[4]; -+ -+ uint16_t tile_x_num; /* x axis tile num / tile size is 8x8 pixel */ -+ uint16_t tile_y_num; /* y axis tile num */ -+ -+ int16_t dst_x_tmp; /* dst pos x = (xstart - xoff) default value 0 */ -+ int16_t dst_y_tmp; /* dst pos y = (ystart - yoff) default value 0 */ -+ -+ uint16_t tile_w; -+ uint16_t tile_h; -+ int16_t tile_start_x_coor; -+ int16_t tile_start_y_coor; -+ int32_t tile_xoff; -+ int32_t tile_yoff; -+ -+ int32_t tile_temp_xstart; -+ int32_t tile_temp_ystart; -+ -+ /* src tile incr */ -+ int32_t x_dx; -+ int32_t x_dy; -+ int32_t y_dx; -+ int32_t y_dy; -+ -+ mdp_img_act dst_ctrl; -+ -+} -+TILE_INFO; -+ -+struct rga_mmu_buf_t { -+ int32_t front; -+ int32_t back; -+ int32_t size; -+ int32_t curr; -+ unsigned int *buf; -+ unsigned int *buf_virtual; -+ -+ struct page **pages; -+}; -+ -+/** -+ * struct for process session which connect to rga -+ * -+ * @author ZhangShengqin (2012-2-15) -+ */ -+typedef struct rga_session { -+ /* a linked list of data so we can access them for debugging */ -+ struct list_head list_session; -+ /* a linked list of register data waiting for process */ -+ struct list_head waiting; -+ /* a linked list of register data in processing */ -+ struct list_head running; -+ /* all coommand this thread done */ -+ atomic_t done; -+ wait_queue_head_t wait; -+ pid_t pid; -+ atomic_t task_running; -+ atomic_t num_done; -+} rga_session; -+ -+struct rga_reg { -+ rga_session *session; -+ struct list_head session_link; /* link to rga service session */ -+ struct list_head status_link; /* link to register set list */ -+ uint32_t sys_reg[RGA_REG_CTRL_LEN]; -+ uint32_t cmd_reg[RGA_REG_CMD_LEN]; -+ -+ uint32_t *MMU_base; -+ uint32_t MMU_len; -+ //atomic_t int_enable; -+ -+ //struct rga_req req; ++}; ++ ++ ++typedef struct TILE_INFO ++{ ++ int64_t matrix[4]; ++ ++ uint16_t tile_x_num; /* x axis tile num / tile size is 8x8 pixel */ ++ uint16_t tile_y_num; /* y axis tile num */ ++ ++ int16_t dst_x_tmp; /* dst pos x = (xstart - xoff) default value 0 */ ++ int16_t dst_y_tmp; /* dst pos y = (ystart - yoff) default value 0 */ ++ ++ uint16_t tile_w; ++ uint16_t tile_h; ++ int16_t tile_start_x_coor; ++ int16_t tile_start_y_coor; ++ int32_t tile_xoff; ++ int32_t tile_yoff; ++ ++ int32_t tile_temp_xstart; ++ int32_t tile_temp_ystart; ++ ++ /* src tile incr */ ++ int32_t x_dx; ++ int32_t x_dy; ++ int32_t y_dx; ++ int32_t y_dy; ++ ++ mdp_img_act dst_ctrl; ++ ++} ++TILE_INFO; ++ ++struct rga_mmu_buf_t { ++ int32_t front; ++ int32_t back; ++ int32_t size; ++ int32_t curr; ++ unsigned int *buf; ++ unsigned int *buf_virtual; ++ ++ struct page **pages; ++}; ++ ++/** ++ * struct for process session which connect to rga ++ * ++ * @author ZhangShengqin (2012-2-15) ++ */ ++typedef struct rga_session { ++ /* a linked list of data so we can access them for debugging */ ++ struct list_head list_session; ++ /* a linked list of register data waiting for process */ ++ struct list_head waiting; ++ /* a linked list of register data in processing */ ++ struct list_head running; ++ /* all coommand this thread done */ ++ atomic_t done; ++ wait_queue_head_t wait; ++ pid_t pid; ++ atomic_t task_running; ++ atomic_t num_done; ++} rga_session; ++ ++struct rga_reg { ++ rga_session *session; ++ struct list_head session_link; /* link to rga service session */ ++ struct list_head status_link; /* link to register set list */ ++ uint32_t sys_reg[RGA_REG_CTRL_LEN]; ++ uint32_t cmd_reg[RGA_REG_CMD_LEN]; ++ ++ uint32_t *MMU_base; ++ uint32_t MMU_len; ++ //atomic_t int_enable; ++ ++ //struct rga_req req; + + struct sg_table *sg_src; + struct sg_table *sg_dst; + + struct dma_buf_attachment *attach_src; + struct dma_buf_attachment *attach_dst; -+}; -+ -+ -+ -+typedef struct rga_service_info { -+ struct mutex lock; -+ struct timer_list timer; /* timer for power off */ -+ struct list_head waiting; /* link to link_reg in struct vpu_reg */ -+ struct list_head running; /* link to link_reg in struct vpu_reg */ -+ struct list_head done; /* link to link_reg in struct vpu_reg */ -+ struct list_head session; /* link to list_session in struct vpu_session */ -+ atomic_t total_running; -+ -+ struct rga_reg *reg; -+ -+ uint32_t cmd_buff[28*8];/* cmd_buff for rga */ -+ uint32_t *pre_scale_buf; ++}; ++ ++ ++ ++typedef struct rga_service_info { ++ struct mutex lock; ++ struct timer_list timer; /* timer for power off */ ++ struct list_head waiting; /* link to link_reg in struct vpu_reg */ ++ struct list_head running; /* link to link_reg in struct vpu_reg */ ++ struct list_head done; /* link to link_reg in struct vpu_reg */ ++ struct list_head session; /* link to list_session in struct vpu_session */ ++ atomic_t total_running; ++ ++ struct rga_reg *reg; ++ ++ uint32_t cmd_buff[28*8];/* cmd_buff for rga */ ++ uint32_t *pre_scale_buf; + atomic_t int_disable; /* 0 int enable 1 int disable */ -+ atomic_t cmd_num; ++ atomic_t cmd_num; + atomic_t src_format_swt; + int last_prc_src_format; + atomic_t rga_working; -+ bool enable; ++ bool enable; + u32 dev_mode; -+ -+ //struct rga_req req[10]; -+ -+ struct mutex mutex; // mutex -+} rga_service_info; -+ -+ -+ -+#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) || defined(CONFIG_ARCH_RK312x) -+#define RGA_BASE 0x1010c000 -+#elif defined(CONFIG_ARCH_RK30) -+#define RGA_BASE 0x10114000 -+#endif -+ -+//General Registers -+#define RGA_SYS_CTRL 0x000 -+#define RGA_CMD_CTRL 0x004 -+#define RGA_CMD_ADDR 0x008 -+#define RGA_STATUS 0x00c -+#define RGA_INT 0x010 -+#define RGA_AXI_ID 0x014 -+#define RGA_MMU_STA_CTRL 0x018 -+#define RGA_MMU_STA 0x01c ++ ++ //struct rga_req req[10]; ++ ++ struct mutex mutex; // mutex ++} rga_service_info; ++ ++ ++ ++#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) || defined(CONFIG_ARCH_RK312x) ++#define RGA_BASE 0x1010c000 ++#elif defined(CONFIG_ARCH_RK30) ++#define RGA_BASE 0x10114000 ++#endif ++ ++//General Registers ++#define RGA_SYS_CTRL 0x000 ++#define RGA_CMD_CTRL 0x004 ++#define RGA_CMD_ADDR 0x008 ++#define RGA_STATUS 0x00c ++#define RGA_INT 0x010 ++#define RGA_AXI_ID 0x014 ++#define RGA_MMU_STA_CTRL 0x018 ++#define RGA_MMU_STA 0x01c +#define RGA_VERSION 0x028 -+ -+//Command code start -+#define RGA_MODE_CTRL 0x100 -+ -+//Source Image Registers -+#define RGA_SRC_Y_MST 0x104 -+#define RGA_SRC_CB_MST 0x108 -+#define RGA_MASK_READ_MST 0x108 //repeat -+#define RGA_SRC_CR_MST 0x10c -+#define RGA_SRC_VIR_INFO 0x110 -+#define RGA_SRC_ACT_INFO 0x114 -+#define RGA_SRC_X_PARA 0x118 -+#define RGA_SRC_Y_PARA 0x11c -+#define RGA_SRC_TILE_XINFO 0x120 -+#define RGA_SRC_TILE_YINFO 0x124 -+#define RGA_SRC_TILE_H_INCR 0x128 -+#define RGA_SRC_TILE_V_INCR 0x12c -+#define RGA_SRC_TILE_OFFSETX 0x130 -+#define RGA_SRC_TILE_OFFSETY 0x134 -+#define RGA_SRC_BG_COLOR 0x138 -+#define RGA_SRC_FG_COLOR 0x13c -+#define RGA_LINE_DRAWING_COLOR 0x13c //repeat -+#define RGA_SRC_TR_COLOR0 0x140 -+#define RGA_CP_GR_A 0x140 //repeat -+#define RGA_SRC_TR_COLOR1 0x144 -+#define RGA_CP_GR_B 0x144 //repeat -+ -+#define RGA_LINE_DRAW 0x148 -+#define RGA_PAT_START_POINT 0x148 //repeat -+ -+//Destination Image Registers -+#define RGA_DST_MST 0x14c -+#define RGA_LUT_MST 0x14c //repeat -+#define RGA_PAT_MST 0x14c //repeat -+#define RGA_LINE_DRAWING_MST 0x14c //repeat -+ -+#define RGA_DST_VIR_INFO 0x150 -+ -+#define RGA_DST_CTR_INFO 0x154 -+#define RGA_LINE_DRAW_XY_INFO 0x154 //repeat -+ -+//Alpha/ROP Registers -+#define RGA_ALPHA_CON 0x158 -+ -+#define RGA_PAT_CON 0x15c -+#define RGA_DST_VIR_WIDTH_PIX 0x15c //repeat -+ -+#define RGA_ROP_CON0 0x160 -+#define RGA_CP_GR_G 0x160 //repeat -+#define RGA_PRESCL_CB_MST 0x160 //repeat -+ -+#define RGA_ROP_CON1 0x164 -+#define RGA_CP_GR_R 0x164 //repeat -+#define RGA_PRESCL_CR_MST 0x164 //repeat -+ -+//MMU Register -+#define RGA_FADING_CON 0x168 -+#define RGA_MMU_CTRL 0x168 //repeat -+ -+#define RGA_MMU_TBL 0x16c //repeat -+ -+#define RGA_YUV_OUT_CFG 0x170 -+#define RGA_DST_UV_MST 0x174 -+ -+ -+#define RGA_BLIT_COMPLETE_EVENT 1 -+ -+long rga_ioctl_kernel(struct rga_req *req); -+ -+#endif /*_RK29_IPP_DRIVER_H_*/ ++ ++//Command code start ++#define RGA_MODE_CTRL 0x100 ++ ++//Source Image Registers ++#define RGA_SRC_Y_MST 0x104 ++#define RGA_SRC_CB_MST 0x108 ++#define RGA_MASK_READ_MST 0x108 //repeat ++#define RGA_SRC_CR_MST 0x10c ++#define RGA_SRC_VIR_INFO 0x110 ++#define RGA_SRC_ACT_INFO 0x114 ++#define RGA_SRC_X_PARA 0x118 ++#define RGA_SRC_Y_PARA 0x11c ++#define RGA_SRC_TILE_XINFO 0x120 ++#define RGA_SRC_TILE_YINFO 0x124 ++#define RGA_SRC_TILE_H_INCR 0x128 ++#define RGA_SRC_TILE_V_INCR 0x12c ++#define RGA_SRC_TILE_OFFSETX 0x130 ++#define RGA_SRC_TILE_OFFSETY 0x134 ++#define RGA_SRC_BG_COLOR 0x138 ++#define RGA_SRC_FG_COLOR 0x13c ++#define RGA_LINE_DRAWING_COLOR 0x13c //repeat ++#define RGA_SRC_TR_COLOR0 0x140 ++#define RGA_CP_GR_A 0x140 //repeat ++#define RGA_SRC_TR_COLOR1 0x144 ++#define RGA_CP_GR_B 0x144 //repeat ++ ++#define RGA_LINE_DRAW 0x148 ++#define RGA_PAT_START_POINT 0x148 //repeat ++ ++//Destination Image Registers ++#define RGA_DST_MST 0x14c ++#define RGA_LUT_MST 0x14c //repeat ++#define RGA_PAT_MST 0x14c //repeat ++#define RGA_LINE_DRAWING_MST 0x14c //repeat ++ ++#define RGA_DST_VIR_INFO 0x150 ++ ++#define RGA_DST_CTR_INFO 0x154 ++#define RGA_LINE_DRAW_XY_INFO 0x154 //repeat ++ ++//Alpha/ROP Registers ++#define RGA_ALPHA_CON 0x158 ++ ++#define RGA_PAT_CON 0x15c ++#define RGA_DST_VIR_WIDTH_PIX 0x15c //repeat ++ ++#define RGA_ROP_CON0 0x160 ++#define RGA_CP_GR_G 0x160 //repeat ++#define RGA_PRESCL_CB_MST 0x160 //repeat ++ ++#define RGA_ROP_CON1 0x164 ++#define RGA_CP_GR_R 0x164 //repeat ++#define RGA_PRESCL_CR_MST 0x164 //repeat ++ ++//MMU Register ++#define RGA_FADING_CON 0x168 ++#define RGA_MMU_CTRL 0x168 //repeat ++ ++#define RGA_MMU_TBL 0x16c //repeat ++ ++#define RGA_YUV_OUT_CFG 0x170 ++#define RGA_DST_UV_MST 0x174 ++ ++ ++#define RGA_BLIT_COMPLETE_EVENT 1 ++ ++long rga_ioctl_kernel(struct rga_req *req); ++ ++#endif /*_RK29_IPP_DRIVER_H_*/ diff --git a/drivers/video/rockchip/rga/rga_drv.c b/drivers/video/rockchip/rga/rga_drv.c new file mode 100644 index 000000000..c5d3672c5 --- /dev/null +++ b/drivers/video/rockchip/rga/rga_drv.c @@ -0,0 +1,2574 @@ -+/* -+ * Copyright (C) 2012 ROCKCHIP, Inc. -+ * -+ * This software is licensed under the terms of the GNU General Public -+ * License version 2, as published by the Free Software Foundation, and -+ * may be copied, distributed, and modified under those terms. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ */ -+ -+#define pr_fmt(fmt) "rga: " fmt -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//#include -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++/* ++ * Copyright (C) 2012 ROCKCHIP, Inc. ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#define pr_fmt(fmt) "rga: " fmt ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++//#include ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include +#include +#include +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) @@ -1839847,42 +1839847,42 @@ index 000000000..c5d3672c5 +#include +#endif + -+#include "rga.h" -+#include "rga_reg_info.h" -+#include "rga_mmu_info.h" -+#include "RGA_API.h" -+ -+#define RGA_TEST_CASE 0 -+ -+#define RGA_TEST_FLUSH_TIME 0 -+#define RGA_INFO_BUS_ERROR 1 -+ -+#define RGA_PRE_SCALE_BUF_SIZE (2048 * 2048 * 4) -+#define RGA_PRE_SCALE_PAGE_SIZE (RGA_PRE_SCALE_BUF_SIZE >> PAGE_SHIFT) -+ -+#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ -+#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ -+ -+#define RGA_MAJOR 255 -+ -+#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) -+#define RK30_RGA_PHYS RK2928_RGA_PHYS -+#define RK30_RGA_SIZE RK2928_RGA_SIZE -+#endif -+#define RGA_RESET_TIMEOUT 1000 -+ -+/* Driver information */ -+#define DRIVER_DESC "RGA Device Driver" -+#define DRIVER_NAME "rga" -+ -+ -+ktime_t rga_start; -+ktime_t rga_end; -+ -+static rga_session rga_session_global; -+ -+long (*rga_ioctl_kernel_p)(struct rga_req *); -+ ++#include "rga.h" ++#include "rga_reg_info.h" ++#include "rga_mmu_info.h" ++#include "RGA_API.h" ++ ++#define RGA_TEST_CASE 0 ++ ++#define RGA_TEST_FLUSH_TIME 0 ++#define RGA_INFO_BUS_ERROR 1 ++ ++#define RGA_PRE_SCALE_BUF_SIZE (2048 * 2048 * 4) ++#define RGA_PRE_SCALE_PAGE_SIZE (RGA_PRE_SCALE_BUF_SIZE >> PAGE_SHIFT) ++ ++#define RGA_POWER_OFF_DELAY 4*HZ /* 4s */ ++#define RGA_TIMEOUT_DELAY 2*HZ /* 2s */ ++ ++#define RGA_MAJOR 255 ++ ++#if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3026) ++#define RK30_RGA_PHYS RK2928_RGA_PHYS ++#define RK30_RGA_SIZE RK2928_RGA_SIZE ++#endif ++#define RGA_RESET_TIMEOUT 1000 ++ ++/* Driver information */ ++#define DRIVER_DESC "RGA Device Driver" ++#define DRIVER_NAME "rga" ++ ++ ++ktime_t rga_start; ++ktime_t rga_end; ++ ++static rga_session rga_session_global; ++ ++long (*rga_ioctl_kernel_p)(struct rga_req *); ++ +#if RGA_DEBUGFS +unsigned char RGA_TEST_REG; +unsigned char RGA_TEST_MSG; @@ -1839891,36 +1839891,36 @@ index 000000000..c5d3672c5 +unsigned char RGA_NONUSE; +unsigned char RGA_INT_FLAG; +#endif -+ ++ +struct rga_drvdata *rga_drvdata; -+rga_service_info rga_service; -+struct rga_mmu_buf_t rga_mmu_buf; -+ -+ -+#if defined(CONFIG_ION_ROCKCHIP) -+extern struct ion_client *rockchip_ion_client_create(const char * name); -+#endif -+ -+static int rga_blit_async(rga_session *session, struct rga_req *req); -+static void rga_del_running_list(void); -+static void rga_del_running_list_timeout(void); -+static void rga_try_set_reg(void); -+ -+ -+/* Logging */ -+#define RGA_DEBUG 1 -+#if RGA_DEBUG -+#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) -+#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) -+#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) -+#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) -+#else -+#define DBG(format, args...) -+#define ERR(format, args...) -+#define WARNING(format, args...) -+#define INFO(format, args...) -+#endif -+ ++rga_service_info rga_service; ++struct rga_mmu_buf_t rga_mmu_buf; ++ ++ ++#if defined(CONFIG_ION_ROCKCHIP) ++extern struct ion_client *rockchip_ion_client_create(const char * name); ++#endif ++ ++static int rga_blit_async(rga_session *session, struct rga_req *req); ++static void rga_del_running_list(void); ++static void rga_del_running_list_timeout(void); ++static void rga_try_set_reg(void); ++ ++ ++/* Logging */ ++#define RGA_DEBUG 1 ++#if RGA_DEBUG ++#define DBG(format, args...) printk(KERN_DEBUG "%s: " format, DRIVER_NAME, ## args) ++#define ERR(format, args...) printk(KERN_ERR "%s: " format, DRIVER_NAME, ## args) ++#define WARNING(format, args...) printk(KERN_WARN "%s: " format, DRIVER_NAME, ## args) ++#define INFO(format, args...) printk(KERN_INFO "%s: " format, DRIVER_NAME, ## args) ++#else ++#define DBG(format, args...) ++#define ERR(format, args...) ++#define WARNING(format, args...) ++#define INFO(format, args...) ++#endif ++ +#if RGA_DEBUGFS +static const char *rga_get_cmd_mode_str(u32 cmd) +{ @@ -1840203,127 +1840203,127 @@ index 000000000..c5d3672c5 +} +#endif + -+static inline void rga_write(u32 b, u32 r) -+{ -+ __raw_writel(b, rga_drvdata->rga_base + r); -+} -+ -+static inline u32 rga_read(u32 r) -+{ -+ return __raw_readl(rga_drvdata->rga_base + r); -+} -+ -+static void rga_soft_reset(void) -+{ -+ u32 i; -+ u32 reg; -+ -+ rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL -+ -+ for(i = 0; i < RGA_RESET_TIMEOUT; i++) -+ { -+ reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL -+ -+ if(reg == 0) -+ break; -+ -+ udelay(1); -+ } -+ -+ if(i == RGA_RESET_TIMEOUT) -+ ERR("soft reset timeout.\n"); -+} -+ -+static void rga_dump(void) -+{ -+ int running; -+ struct rga_reg *reg, *reg_tmp; -+ rga_session *session, *session_tmp; -+ -+ running = atomic_read(&rga_service.total_running); -+ printk("rga total_running %d\n", running); -+ -+ #if 0 -+ -+ /* Dump waiting list info */ -+ if (!list_empty(&rga_service.waiting)) -+ { -+ list_head *next; -+ -+ next = &rga_service.waiting; -+ -+ printk("rga_service dump waiting list\n"); -+ -+ do -+ { -+ reg = list_entry(next->next, struct rga_reg, status_link); -+ running = atomic_read(®->session->task_running); -+ num_done = atomic_read(®->session->num_done); -+ printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); -+ next = next->next; -+ } -+ while(!list_empty(next)); -+ } -+ -+ /* Dump running list info */ -+ if (!list_empty(&rga_service.running)) -+ { -+ printk("rga_service dump running list\n"); -+ -+ list_head *next; -+ -+ next = &rga_service.running; -+ do -+ { -+ reg = list_entry(next->next, struct rga_reg, status_link); -+ running = atomic_read(®->session->task_running); -+ num_done = atomic_read(®->session->num_done); -+ printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); -+ next = next->next; -+ } -+ while(!list_empty(next)); -+ } -+ #endif -+ -+ list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) -+ { -+ printk("session pid %d:\n", session->pid); -+ running = atomic_read(&session->task_running); -+ printk("task_running %d\n", running); -+ list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) -+ { ++static inline void rga_write(u32 b, u32 r) ++{ ++ __raw_writel(b, rga_drvdata->rga_base + r); ++} ++ ++static inline u32 rga_read(u32 r) ++{ ++ return __raw_readl(rga_drvdata->rga_base + r); ++} ++ ++static void rga_soft_reset(void) ++{ ++ u32 i; ++ u32 reg; ++ ++ rga_write(1, RGA_SYS_CTRL); //RGA_SYS_CTRL ++ ++ for(i = 0; i < RGA_RESET_TIMEOUT; i++) ++ { ++ reg = rga_read(RGA_SYS_CTRL) & 1; //RGA_SYS_CTRL ++ ++ if(reg == 0) ++ break; ++ ++ udelay(1); ++ } ++ ++ if(i == RGA_RESET_TIMEOUT) ++ ERR("soft reset timeout.\n"); ++} ++ ++static void rga_dump(void) ++{ ++ int running; ++ struct rga_reg *reg, *reg_tmp; ++ rga_session *session, *session_tmp; ++ ++ running = atomic_read(&rga_service.total_running); ++ printk("rga total_running %d\n", running); ++ ++ #if 0 ++ ++ /* Dump waiting list info */ ++ if (!list_empty(&rga_service.waiting)) ++ { ++ list_head *next; ++ ++ next = &rga_service.waiting; ++ ++ printk("rga_service dump waiting list\n"); ++ ++ do ++ { ++ reg = list_entry(next->next, struct rga_reg, status_link); ++ running = atomic_read(®->session->task_running); ++ num_done = atomic_read(®->session->num_done); ++ printk("rga session pid %d, done %d, running %d\n", reg->session->pid, num_done, running); ++ next = next->next; ++ } ++ while(!list_empty(next)); ++ } ++ ++ /* Dump running list info */ ++ if (!list_empty(&rga_service.running)) ++ { ++ printk("rga_service dump running list\n"); ++ ++ list_head *next; ++ ++ next = &rga_service.running; ++ do ++ { ++ reg = list_entry(next->next, struct rga_reg, status_link); ++ running = atomic_read(®->session->task_running); ++ num_done = atomic_read(®->session->num_done); ++ printk("rga session pid %d, done %d, running %d:\n", reg->session->pid, num_done, running); ++ next = next->next; ++ } ++ while(!list_empty(next)); ++ } ++ #endif ++ ++ list_for_each_entry_safe(session, session_tmp, &rga_service.session, list_session) ++ { ++ printk("session pid %d:\n", session->pid); ++ running = atomic_read(&session->task_running); ++ printk("task_running %d\n", running); ++ list_for_each_entry_safe(reg, reg_tmp, &session->waiting, session_link) ++ { + printk("waiting register set 0x %.lu\n", (unsigned long)reg); -+ } -+ list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) -+ { ++ } ++ list_for_each_entry_safe(reg, reg_tmp, &session->running, session_link) ++ { + printk("running register set 0x %.lu\n", (unsigned long)reg); -+ } -+ } -+} -+ -+static inline void rga_queue_power_off_work(void) -+{ ++ } ++ } ++} ++ ++static inline void rga_queue_power_off_work(void) ++{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) -+ queue_delayed_work(system_wq, &rga_drvdata->power_off_work, RGA_POWER_OFF_DELAY); ++ queue_delayed_work(system_wq, &rga_drvdata->power_off_work, RGA_POWER_OFF_DELAY); +#else + queue_delayed_work(system_nrt_wq, &rga_drvdata->power_off_work, RGA_POWER_OFF_DELAY); +#endif -+} -+ -+/* Caller must hold rga_service.lock */ -+static void rga_power_on(void) -+{ -+ static ktime_t last; -+ ktime_t now = ktime_get(); -+ -+ if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { -+ cancel_delayed_work_sync(&rga_drvdata->power_off_work); -+ rga_queue_power_off_work(); -+ last = now; -+ } -+ if (rga_service.enable) -+ return; -+ ++} ++ ++/* Caller must hold rga_service.lock */ ++static void rga_power_on(void) ++{ ++ static ktime_t last; ++ ktime_t now = ktime_get(); ++ ++ if (ktime_to_ns(ktime_sub(now, last)) > NSEC_PER_SEC) { ++ cancel_delayed_work_sync(&rga_drvdata->power_off_work); ++ rga_queue_power_off_work(); ++ last = now; ++ } ++ if (rga_service.enable) ++ return; ++ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + clk_prepare_enable(rga_drvdata->aclk_rga); + clk_prepare_enable(rga_drvdata->hclk_rga); @@ -1840335,27 +1840335,27 @@ index 000000000..c5d3672c5 + clk_prepare_enable(rga_drvdata->pd_rga); +#endif + -+ wake_lock(&rga_drvdata->wake_lock); -+ rga_service.enable = true; -+} -+ -+/* Caller must hold rga_service.lock */ -+static void rga_power_off(void) -+{ -+ int total_running; -+ -+ if (!rga_service.enable) { -+ return; -+ } -+ -+ total_running = atomic_read(&rga_service.total_running); -+ if (total_running) { -+ pr_err("power off when %d task running!!\n", total_running); -+ mdelay(50); -+ pr_err("delay 50 ms for running task\n"); -+ rga_dump(); -+ } -+ ++ wake_lock(&rga_drvdata->wake_lock); ++ rga_service.enable = true; ++} ++ ++/* Caller must hold rga_service.lock */ ++static void rga_power_off(void) ++{ ++ int total_running; ++ ++ if (!rga_service.enable) { ++ return; ++ } ++ ++ total_running = atomic_read(&rga_service.total_running); ++ if (total_running) { ++ pr_err("power off when %d task running!!\n", total_running); ++ mdelay(50); ++ pr_err("delay 50 ms for running task\n"); ++ rga_dump(); ++ } ++ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) + pm_runtime_put(rga_drvdata->dev); + clk_disable_unprepare(rga_drvdata->aclk_rga); @@ -1840366,17 +1840366,17 @@ index 000000000..c5d3672c5 + clk_disable_unprepare(rga_drvdata->aclk_rga); + clk_disable_unprepare(rga_drvdata->hclk_rga); +#endif -+ wake_unlock(&rga_drvdata->wake_lock); -+ rga_service.enable = false; -+} -+ -+static void rga_power_off_work(struct work_struct *work) -+{ -+ if (mutex_trylock(&rga_service.lock)) { -+ rga_power_off(); -+ mutex_unlock(&rga_service.lock); -+ } else { -+ /* Come back later if the device is busy... */ ++ wake_unlock(&rga_drvdata->wake_lock); ++ rga_service.enable = false; ++} ++ ++static void rga_power_off_work(struct work_struct *work) ++{ ++ if (mutex_trylock(&rga_service.lock)) { ++ rga_power_off(); ++ mutex_unlock(&rga_service.lock); ++ } else { ++ /* Come back later if the device is busy... */ + + rga_queue_power_off_work(); + } @@ -1840510,7 +1840510,7 @@ index 000000000..c5d3672c5 + cmd_buf = (uint32_t *)rga_service.cmd_buff + offset*32; + reg_p = (uint32_t *)reg->cmd_reg; + -+ for(i=0; i<32; i++) ++ for(i=0; i<32; i++) + cmd_buf[i] = reg_p[i]; +} + @@ -1840903,9 +1840903,9 @@ index 000000000..c5d3672c5 + struct dma_buf_attachment *attach = NULL; + struct device *rga_dev = NULL; + struct sg_table *sgt = NULL; -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) -+ struct iosys_map map; -+#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) ++ struct iosys_map map; ++#endif + struct dma_buf *dma_buf = NULL; + u32 vir_w, vir_h; + int yrgb_addr = -1; @@ -1840934,20 +1840934,20 @@ index 000000000..c5d3672c5 + } +#if RGA_DEBUGFS + if (RGA_CHECK_MODE) { -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) -+ ret = dma_buf_vmap(dma_buf, &map); -+ vaddr = ret ? NULL : map.vaddr; -+#else ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) ++ ret = dma_buf_vmap(dma_buf, &map); ++ vaddr = ret ? NULL : map.vaddr; ++#else + vaddr = dma_buf_vmap(dma_buf); -+#endif ++#endif + if (vaddr) + rga_memory_check(vaddr, img->vir_w, img->vir_h, + img->format, img->yrgb_addr); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) -+ dma_buf_vunmap(dma_buf, &map); -+#else ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0) ++ dma_buf_vunmap(dma_buf, &map); ++#else + dma_buf_vunmap(dma_buf, vaddr); -+#endif ++#endif + } +#endif + *pattach = attach; @@ -1842077,295 +1842077,295 @@ index 000000000..c5d3672c5 +} +#endif +#endif -+ -+void rga_test_0(void); -+void rga_test_1(void); -+ -+static int __init rga_init(void) -+{ -+ int i, ret; -+ void * pre_scale_page_buf; -+ uint32_t *pre_scale_page_table; ++ ++void rga_test_0(void); ++void rga_test_1(void); ++ ++static int __init rga_init(void) ++{ ++ int i, ret; ++ void * pre_scale_page_buf; ++ uint32_t *pre_scale_page_table; + uint32_t *mmu_base; -+ struct page **pages; -+ -+ /* malloc pre scale mid buf mmu table */ -+ pre_scale_page_table = kzalloc(RGA_PRE_SCALE_PAGE_SIZE * sizeof(*pre_scale_page_table), -+ GFP_KERNEL); -+ if(pre_scale_page_table == NULL) { -+ pr_err("RGA alloc pre-scale page table failed.\n"); -+ return -ENOMEM; -+ } -+ -+ /* alloc reserved pre-scale buf */ -+ for(i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) { -+ pre_scale_page_buf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); -+ if(pre_scale_page_buf == NULL) { -+ printk(KERN_ERR "RGA init pre scale page_table[%d] falied\n", i); -+ ret = -ENOMEM; -+ goto free_pre_scale_page_table; -+ } -+ pre_scale_page_table[i] = (uint32_t)virt_to_phys(pre_scale_page_buf); -+ } -+ -+ mmu_base = kmalloc(1024 * 256, GFP_KERNEL); -+ if (mmu_base == NULL) { -+ pr_err("RGA alloc mmu buffer failed.\n"); -+ ret = -ENOMEM; -+ goto free_pre_scale_page_table; -+ } -+ -+ pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); -+ if (pages == NULL) { -+ pr_err("RGA alloc pages buffer failed.\n"); -+ ret = -ENOMEM; -+ goto free_mmu_base; -+ } -+ -+ ret = platform_driver_register(&rga_driver); -+ if (ret != 0) { -+ printk(KERN_ERR "Platform device register failed (%d).\n", ret); -+ goto free_pages_buf; -+ } -+ -+ rga_service.pre_scale_buf = pre_scale_page_table; -+ -+ rga_mmu_buf.buf_virtual = mmu_base; ++ struct page **pages; ++ ++ /* malloc pre scale mid buf mmu table */ ++ pre_scale_page_table = kzalloc(RGA_PRE_SCALE_PAGE_SIZE * sizeof(*pre_scale_page_table), ++ GFP_KERNEL); ++ if(pre_scale_page_table == NULL) { ++ pr_err("RGA alloc pre-scale page table failed.\n"); ++ return -ENOMEM; ++ } ++ ++ /* alloc reserved pre-scale buf */ ++ for(i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) { ++ pre_scale_page_buf = (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO); ++ if(pre_scale_page_buf == NULL) { ++ printk(KERN_ERR "RGA init pre scale page_table[%d] falied\n", i); ++ ret = -ENOMEM; ++ goto free_pre_scale_page_table; ++ } ++ pre_scale_page_table[i] = (uint32_t)virt_to_phys(pre_scale_page_buf); ++ } ++ ++ mmu_base = kmalloc(1024 * 256, GFP_KERNEL); ++ if (mmu_base == NULL) { ++ pr_err("RGA alloc mmu buffer failed.\n"); ++ ret = -ENOMEM; ++ goto free_pre_scale_page_table; ++ } ++ ++ pages = kmalloc((32768)* sizeof(struct page *), GFP_KERNEL); ++ if (pages == NULL) { ++ pr_err("RGA alloc pages buffer failed.\n"); ++ ret = -ENOMEM; ++ goto free_mmu_base; ++ } ++ ++ ret = platform_driver_register(&rga_driver); ++ if (ret != 0) { ++ printk(KERN_ERR "Platform device register failed (%d).\n", ret); ++ goto free_pages_buf; ++ } ++ ++ rga_service.pre_scale_buf = pre_scale_page_table; ++ ++ rga_mmu_buf.buf_virtual = mmu_base; +#if (defined(CONFIG_ARM) && defined(CONFIG_ARM_LPAE)) + rga_mmu_buf.buf = (uint32_t *)(uint32_t)virt_to_phys((void *)((unsigned long)mmu_base)); +#else + rga_mmu_buf.buf = (uint32_t *)virt_to_phys((void *)((unsigned long)mmu_base)); +#endif -+ rga_mmu_buf.front = 0; -+ rga_mmu_buf.back = 64*1024; -+ rga_mmu_buf.size = 64*1024; -+ -+ rga_mmu_buf.pages = pages; -+ -+ rga_session_global.pid = 0x0000ffff; -+ INIT_LIST_HEAD(&rga_session_global.waiting); -+ INIT_LIST_HEAD(&rga_session_global.running); -+ INIT_LIST_HEAD(&rga_session_global.list_session); -+ -+ INIT_LIST_HEAD(&rga_service.waiting); -+ INIT_LIST_HEAD(&rga_service.running); -+ INIT_LIST_HEAD(&rga_service.done); -+ INIT_LIST_HEAD(&rga_service.session); -+ -+ init_waitqueue_head(&rga_session_global.wait); -+ //mutex_lock(&rga_service.lock); -+ list_add_tail(&rga_session_global.list_session, &rga_service.session); -+ //mutex_unlock(&rga_service.lock); -+ atomic_set(&rga_session_global.task_running, 0); -+ atomic_set(&rga_session_global.num_done, 0); -+ ++ rga_mmu_buf.front = 0; ++ rga_mmu_buf.back = 64*1024; ++ rga_mmu_buf.size = 64*1024; ++ ++ rga_mmu_buf.pages = pages; ++ ++ rga_session_global.pid = 0x0000ffff; ++ INIT_LIST_HEAD(&rga_session_global.waiting); ++ INIT_LIST_HEAD(&rga_session_global.running); ++ INIT_LIST_HEAD(&rga_session_global.list_session); ++ ++ INIT_LIST_HEAD(&rga_service.waiting); ++ INIT_LIST_HEAD(&rga_service.running); ++ INIT_LIST_HEAD(&rga_service.done); ++ INIT_LIST_HEAD(&rga_service.session); ++ ++ init_waitqueue_head(&rga_session_global.wait); ++ //mutex_lock(&rga_service.lock); ++ list_add_tail(&rga_session_global.list_session, &rga_service.session); ++ //mutex_unlock(&rga_service.lock); ++ atomic_set(&rga_session_global.task_running, 0); ++ atomic_set(&rga_session_global.num_done, 0); ++ +#if RGA_TEST_CASE + rga_test_0(); +#endif +#if RGA_DEBUGFS + rga_debugfs_add(); +#endif -+ -+ INFO("RGA Module initialized.\n"); -+ -+ return 0; -+ -+free_pages_buf: -+ kfree(pages); -+ -+free_mmu_base: -+ kfree(mmu_base); -+ -+free_pre_scale_page_table: -+ for (i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) -+ if (pre_scale_page_table[i] != 0) -+ kfree(phys_to_virt((phys_addr_t)pre_scale_page_table[i])); -+ -+ kfree(pre_scale_page_table); -+ -+ return ret; -+} -+ -+static void __exit rga_exit(void) -+{ -+ phys_addr_t pre_scale_buf; -+ -+ rga_power_off(); -+ -+ if (rga_service.pre_scale_buf != NULL) { -+ pre_scale_buf = (phys_addr_t)rga_service.pre_scale_buf[0]; -+ if (pre_scale_buf) -+ kfree(phys_to_virt(pre_scale_buf)); -+ kfree(rga_service.pre_scale_buf); -+ } ++ ++ INFO("RGA Module initialized.\n"); ++ ++ return 0; ++ ++free_pages_buf: ++ kfree(pages); ++ ++free_mmu_base: ++ kfree(mmu_base); ++ ++free_pre_scale_page_table: ++ for (i = 0; i < RGA_PRE_SCALE_PAGE_SIZE; i++) ++ if (pre_scale_page_table[i] != 0) ++ kfree(phys_to_virt((phys_addr_t)pre_scale_page_table[i])); ++ ++ kfree(pre_scale_page_table); ++ ++ return ret; ++} ++ ++static void __exit rga_exit(void) ++{ ++ phys_addr_t pre_scale_buf; ++ ++ rga_power_off(); ++ ++ if (rga_service.pre_scale_buf != NULL) { ++ pre_scale_buf = (phys_addr_t)rga_service.pre_scale_buf[0]; ++ if (pre_scale_buf) ++ kfree(phys_to_virt(pre_scale_buf)); ++ kfree(rga_service.pre_scale_buf); ++ } + kfree(rga_mmu_buf.buf_virtual); + kfree(rga_mmu_buf.pages); + -+ platform_driver_unregister(&rga_driver); -+} ++ platform_driver_unregister(&rga_driver); ++} + +#if RGA_TEST_CASE + -+extern struct fb_info * rk_get_fb(int fb_id); -+EXPORT_SYMBOL(rk_get_fb); -+ -+extern void rk_direct_fb_show(struct fb_info * fbi); -+EXPORT_SYMBOL(rk_direct_fb_show); -+ -+unsigned int src_buf[1920*1080]; -+unsigned int dst_buf[1920*1080]; -+//unsigned int tmp_buf[1920*1080 * 2]; -+ -+void rga_test_0(void) -+{ -+ struct rga_req req; -+ rga_session session; -+ unsigned int *src, *dst; -+ uint32_t i, j; -+ uint8_t *p; -+ uint8_t t; -+ uint32_t *dst0, *dst1, *dst2; -+ -+ struct fb_info *fb; -+ -+ session.pid = current->pid; -+ INIT_LIST_HEAD(&session.waiting); -+ INIT_LIST_HEAD(&session.running); -+ INIT_LIST_HEAD(&session.list_session); -+ init_waitqueue_head(&session.wait); -+ /* no need to protect */ -+ list_add_tail(&session.list_session, &rga_service.session); -+ atomic_set(&session.task_running, 0); -+ atomic_set(&session.num_done, 0); -+ //file->private_data = (void *)session; -+ -+ fb = rk_get_fb(0); -+ -+ memset(&req, 0, sizeof(struct rga_req)); -+ src = src_buf; -+ dst = dst_buf; -+ -+ memset(src_buf, 0x80, 1024*600*4); -+ -+ dmac_flush_range(&src_buf[0], &src_buf[1024*600]); -+ outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); -+ -+ -+ #if 0 -+ memset(src_buf, 0x80, 800*480*4); -+ memset(dst_buf, 0xcc, 800*480*4); -+ -+ dmac_flush_range(&dst_buf[0], &dst_buf[800*480]); -+ outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480])); -+ #endif -+ -+ dst0 = &dst_buf[0]; -+ //dst1 = &dst_buf[1280*800*4]; -+ //dst2 = &dst_buf[1280*800*4*2]; -+ -+ i = j = 0; -+ -+ printk("\n********************************\n"); -+ printk("************ RGA_TEST ************\n"); -+ printk("********************************\n\n"); -+ -+ req.src.act_w = 1024; -+ req.src.act_h = 600; -+ -+ req.src.vir_w = 1024; -+ req.src.vir_h = 600; -+ req.src.yrgb_addr = (uint32_t)virt_to_phys(src); -+ req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); -+ req.src.v_addr = (uint32_t)virt_to_phys(src); -+ req.src.format = RK_FORMAT_RGBA_8888; -+ -+ req.dst.act_w = 600; -+ req.dst.act_h = 352; -+ -+ req.dst.vir_w = 1280; -+ req.dst.vir_h = 800; -+ req.dst.x_offset = 600; -+ req.dst.y_offset = 0; -+ -+ dst = dst0; -+ -+ req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); -+ -+ //req.dst.format = RK_FORMAT_RGB_565; -+ -+ req.clip.xmin = 0; -+ req.clip.xmax = 1279; -+ req.clip.ymin = 0; -+ req.clip.ymax = 799; -+ -+ //req.render_mode = color_fill_mode; -+ //req.fg_color = 0x80ffffff; -+ -+ req.rotate_mode = 1; -+ //req.scale_mode = 2; -+ -+ //req.alpha_rop_flag = 0; -+ //req.alpha_rop_mode = 0x19; -+ //req.PD_mode = 3; -+ -+ req.sina = 65536; -+ req.cosa = 0; -+ -+ //req.mmu_info.mmu_flag = 0x21; -+ //req.mmu_info.mmu_en = 1; -+ -+ //printk("src = %.8x\n", req.src.yrgb_addr); -+ //printk("src = %.8x\n", req.src.uv_addr); -+ //printk("dst = %.8x\n", req.dst.yrgb_addr); -+ -+ -+ rga_blit_sync(&session, &req); -+ -+ #if 1 -+ fb->var.bits_per_pixel = 32; -+ -+ fb->var.xres = 1280; -+ fb->var.yres = 800; -+ -+ fb->var.red.length = 8; -+ fb->var.red.offset = 0; -+ fb->var.red.msb_right = 0; -+ -+ fb->var.green.length = 8; -+ fb->var.green.offset = 8; -+ fb->var.green.msb_right = 0; -+ -+ fb->var.blue.length = 8; -+ -+ fb->var.blue.offset = 16; -+ fb->var.blue.msb_right = 0; -+ -+ fb->var.transp.length = 8; -+ fb->var.transp.offset = 24; -+ fb->var.transp.msb_right = 0; -+ -+ fb->var.nonstd &= (~0xff); -+ fb->var.nonstd |= 1; -+ -+ fb->fix.smem_start = virt_to_phys(dst); -+ -+ rk_direct_fb_show(fb); -+ #endif -+ -+} -+ -+#endif ++extern struct fb_info * rk_get_fb(int fb_id); ++EXPORT_SYMBOL(rk_get_fb); ++ ++extern void rk_direct_fb_show(struct fb_info * fbi); ++EXPORT_SYMBOL(rk_direct_fb_show); ++ ++unsigned int src_buf[1920*1080]; ++unsigned int dst_buf[1920*1080]; ++//unsigned int tmp_buf[1920*1080 * 2]; ++ ++void rga_test_0(void) ++{ ++ struct rga_req req; ++ rga_session session; ++ unsigned int *src, *dst; ++ uint32_t i, j; ++ uint8_t *p; ++ uint8_t t; ++ uint32_t *dst0, *dst1, *dst2; ++ ++ struct fb_info *fb; ++ ++ session.pid = current->pid; ++ INIT_LIST_HEAD(&session.waiting); ++ INIT_LIST_HEAD(&session.running); ++ INIT_LIST_HEAD(&session.list_session); ++ init_waitqueue_head(&session.wait); ++ /* no need to protect */ ++ list_add_tail(&session.list_session, &rga_service.session); ++ atomic_set(&session.task_running, 0); ++ atomic_set(&session.num_done, 0); ++ //file->private_data = (void *)session; ++ ++ fb = rk_get_fb(0); ++ ++ memset(&req, 0, sizeof(struct rga_req)); ++ src = src_buf; ++ dst = dst_buf; ++ ++ memset(src_buf, 0x80, 1024*600*4); ++ ++ dmac_flush_range(&src_buf[0], &src_buf[1024*600]); ++ outer_flush_range(virt_to_phys(&src_buf[0]),virt_to_phys(&src_buf[1024*600])); ++ ++ ++ #if 0 ++ memset(src_buf, 0x80, 800*480*4); ++ memset(dst_buf, 0xcc, 800*480*4); ++ ++ dmac_flush_range(&dst_buf[0], &dst_buf[800*480]); ++ outer_flush_range(virt_to_phys(&dst_buf[0]),virt_to_phys(&dst_buf[800*480])); ++ #endif ++ ++ dst0 = &dst_buf[0]; ++ //dst1 = &dst_buf[1280*800*4]; ++ //dst2 = &dst_buf[1280*800*4*2]; ++ ++ i = j = 0; ++ ++ printk("\n********************************\n"); ++ printk("************ RGA_TEST ************\n"); ++ printk("********************************\n\n"); ++ ++ req.src.act_w = 1024; ++ req.src.act_h = 600; ++ ++ req.src.vir_w = 1024; ++ req.src.vir_h = 600; ++ req.src.yrgb_addr = (uint32_t)virt_to_phys(src); ++ req.src.uv_addr = (uint32_t)(req.src.yrgb_addr + 1080*1920); ++ req.src.v_addr = (uint32_t)virt_to_phys(src); ++ req.src.format = RK_FORMAT_RGBA_8888; ++ ++ req.dst.act_w = 600; ++ req.dst.act_h = 352; ++ ++ req.dst.vir_w = 1280; ++ req.dst.vir_h = 800; ++ req.dst.x_offset = 600; ++ req.dst.y_offset = 0; ++ ++ dst = dst0; ++ ++ req.dst.yrgb_addr = ((uint32_t)virt_to_phys(dst)); ++ ++ //req.dst.format = RK_FORMAT_RGB_565; ++ ++ req.clip.xmin = 0; ++ req.clip.xmax = 1279; ++ req.clip.ymin = 0; ++ req.clip.ymax = 799; ++ ++ //req.render_mode = color_fill_mode; ++ //req.fg_color = 0x80ffffff; ++ ++ req.rotate_mode = 1; ++ //req.scale_mode = 2; ++ ++ //req.alpha_rop_flag = 0; ++ //req.alpha_rop_mode = 0x19; ++ //req.PD_mode = 3; ++ ++ req.sina = 65536; ++ req.cosa = 0; ++ ++ //req.mmu_info.mmu_flag = 0x21; ++ //req.mmu_info.mmu_en = 1; ++ ++ //printk("src = %.8x\n", req.src.yrgb_addr); ++ //printk("src = %.8x\n", req.src.uv_addr); ++ //printk("dst = %.8x\n", req.dst.yrgb_addr); ++ ++ ++ rga_blit_sync(&session, &req); ++ ++ #if 1 ++ fb->var.bits_per_pixel = 32; ++ ++ fb->var.xres = 1280; ++ fb->var.yres = 800; ++ ++ fb->var.red.length = 8; ++ fb->var.red.offset = 0; ++ fb->var.red.msb_right = 0; ++ ++ fb->var.green.length = 8; ++ fb->var.green.offset = 8; ++ fb->var.green.msb_right = 0; ++ ++ fb->var.blue.length = 8; ++ ++ fb->var.blue.offset = 16; ++ fb->var.blue.msb_right = 0; ++ ++ fb->var.transp.length = 8; ++ fb->var.transp.offset = 24; ++ fb->var.transp.msb_right = 0; ++ ++ fb->var.nonstd &= (~0xff); ++ fb->var.nonstd |= 1; ++ ++ fb->fix.smem_start = virt_to_phys(dst); ++ ++ rk_direct_fb_show(fb); ++ #endif ++ ++} ++ ++#endif +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)) +fs_initcall(rga_init); +#else +module_init(rga_init); +#endif -+module_exit(rga_exit); -+ -+/* Module information */ -+MODULE_AUTHOR("zsq@rock-chips.com"); -+MODULE_DESCRIPTION("Driver for rga device"); -+MODULE_LICENSE("GPL"); ++module_exit(rga_exit); ++ ++/* Module information */ ++MODULE_AUTHOR("zsq@rock-chips.com"); ++MODULE_DESCRIPTION("Driver for rga device"); ++MODULE_LICENSE("GPL"); diff --git a/drivers/video/rockchip/rga/rga_mmu_info.c b/drivers/video/rockchip/rga/rga_mmu_info.c new file mode 100644 index 000000000..32a99d53b @@ -1842373,49 +1842373,49 @@ index 000000000..32a99d53b +++ b/drivers/video/rockchip/rga/rga_mmu_info.c @@ -0,0 +1,1325 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "rga_mmu_info.h" -+#include -+ -+extern rga_service_info rga_service; -+extern struct rga_mmu_buf_t rga_mmu_buf; ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "rga_mmu_info.h" ++#include ++ ++extern rga_service_info rga_service; ++extern struct rga_mmu_buf_t rga_mmu_buf; + +#if RGA_DEBUGFS +extern int RGA_CHECK_MODE; +#endif -+ ++ +#define KERNEL_SPACE_VALID 0xc0000000 + +void rga_dma_flush_range(void *pstart, void *pend) +{ + dma_sync_single_for_device(rga_drvdata->dev, virt_to_phys(pstart), pend - pstart, DMA_TO_DEVICE); +} -+ -+static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size) -+{ -+ mutex_lock(&rga_service.lock); -+ t->front += size; -+ mutex_unlock(&rga_service.lock); -+ -+ return 0; ++ ++static int rga_mmu_buf_get(struct rga_mmu_buf_t *t, uint32_t size) ++{ ++ mutex_lock(&rga_service.lock); ++ t->front += size; ++ mutex_unlock(&rga_service.lock); ++ ++ return 0; +} + +static void rga_current_mm_read_lock(struct mm_struct *mm) @@ -1842456,217 +1842456,217 @@ index 000000000..32a99d53b + pageCount, writeFlag ? FOLL_WRITE : 0, pages, + NULL, NULL); + #endif -+} -+ -+static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size) -+{ -+ int ret = 0; -+ -+ mutex_lock(&rga_service.lock); -+ if ((t->back - t->front) > t->size) { -+ if(t->front + size > t->back - t->size) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ } else { -+ if ((t->front + size) > t->back) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ if (t->front + size > t->size) { -+ if (size > (t->back - t->size)) { -+ ret = -ENOMEM; -+ goto out; -+ } -+ t->front = 0; -+ } -+ } -+ -+out: -+ mutex_unlock(&rga_service.lock); -+ return ret; -+} -+ -+static int rga_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) -+{ -+ unsigned long start, end; -+ uint32_t pageCount; -+ -+ end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ start = Mem >> PAGE_SHIFT; -+ pageCount = end - start; -+ *StartAddr = start; -+ return pageCount; -+} -+ -+static int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, -+ int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) -+{ -+ uint32_t size_yrgb = 0; -+ uint32_t size_uv = 0; -+ uint32_t size_v = 0; -+ uint32_t stride = 0; -+ unsigned long start, end; -+ uint32_t pageCount; -+ -+ switch(format) -+ { -+ case RK_FORMAT_RGBA_8888 : -+ stride = (w * 4 + 3) & (~3); -+ size_yrgb = stride*h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_RGBX_8888 : -+ stride = (w * 4 + 3) & (~3); -+ size_yrgb = stride*h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_RGB_888 : -+ stride = (w * 3 + 3) & (~3); -+ size_yrgb = stride*h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_BGRA_8888 : -+ size_yrgb = w*h*4; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_RGB_565 : -+ stride = (w*2 + 3) & (~3); -+ size_yrgb = stride * h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_RGBA_5551 : -+ stride = (w*2 + 3) & (~3); -+ size_yrgb = stride * h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_RGBA_4444 : -+ stride = (w*2 + 3) & (~3); -+ size_yrgb = stride * h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ case RK_FORMAT_BGR_888 : -+ stride = (w*3 + 3) & (~3); -+ size_yrgb = stride * h; -+ start = yrgb_addr >> PAGE_SHIFT; -+ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; -+ break; -+ -+ /* YUV FORMAT */ -+ case RK_FORMAT_YCbCr_422_SP : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = stride * h; -+ start = MIN(yrgb_addr, uv_addr); -+ -+ start >>= PAGE_SHIFT; -+ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ case RK_FORMAT_YCbCr_422_P : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = ((stride >> 1) * h); -+ size_v = ((stride >> 1) * h); -+ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); -+ start = start >> PAGE_SHIFT; -+ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ case RK_FORMAT_YCbCr_420_SP : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = (stride * (h >> 1)); -+ start = MIN(yrgb_addr, uv_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ case RK_FORMAT_YCbCr_420_P : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = ((stride >> 1) * (h >> 1)); -+ size_v = ((stride >> 1) * (h >> 1)); -+ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ -+ case RK_FORMAT_YCrCb_422_SP : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = stride * h; -+ start = MIN(yrgb_addr, uv_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ case RK_FORMAT_YCrCb_422_P : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = ((stride >> 1) * h); -+ size_v = ((stride >> 1) * h); -+ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ -+ case RK_FORMAT_YCrCb_420_SP : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = (stride * (h >> 1)); -+ start = MIN(yrgb_addr, uv_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ case RK_FORMAT_YCrCb_420_P : -+ stride = (w + 3) & (~3); -+ size_yrgb = stride * h; -+ size_uv = ((stride >> 1) * (h >> 1)); -+ size_v = ((stride >> 1) * (h >> 1)); -+ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); -+ start >>= PAGE_SHIFT; -+ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); -+ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; -+ pageCount = end - start; -+ break; -+ #if 0 -+ case RK_FORMAT_BPP1 : -+ break; -+ case RK_FORMAT_BPP2 : -+ break; -+ case RK_FORMAT_BPP4 : -+ break; -+ case RK_FORMAT_BPP8 : -+ break; -+ #endif -+ default : -+ pageCount = 0; -+ start = 0; -+ break; -+ } -+ -+ *StartAddr = start; -+ return pageCount; -+} -+ ++} ++ ++static int rga_mmu_buf_get_try(struct rga_mmu_buf_t *t, uint32_t size) ++{ ++ int ret = 0; ++ ++ mutex_lock(&rga_service.lock); ++ if ((t->back - t->front) > t->size) { ++ if(t->front + size > t->back - t->size) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ } else { ++ if ((t->front + size) > t->back) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ if (t->front + size > t->size) { ++ if (size > (t->back - t->size)) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ t->front = 0; ++ } ++ } ++ ++out: ++ mutex_unlock(&rga_service.lock); ++ return ret; ++} ++ ++static int rga_mem_size_cal(unsigned long Mem, uint32_t MemSize, unsigned long *StartAddr) ++{ ++ unsigned long start, end; ++ uint32_t pageCount; ++ ++ end = (Mem + (MemSize + PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ start = Mem >> PAGE_SHIFT; ++ pageCount = end - start; ++ *StartAddr = start; ++ return pageCount; ++} ++ ++static int rga_buf_size_cal(unsigned long yrgb_addr, unsigned long uv_addr, unsigned long v_addr, ++ int format, uint32_t w, uint32_t h, unsigned long *StartAddr ) ++{ ++ uint32_t size_yrgb = 0; ++ uint32_t size_uv = 0; ++ uint32_t size_v = 0; ++ uint32_t stride = 0; ++ unsigned long start, end; ++ uint32_t pageCount; ++ ++ switch(format) ++ { ++ case RK_FORMAT_RGBA_8888 : ++ stride = (w * 4 + 3) & (~3); ++ size_yrgb = stride*h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_RGBX_8888 : ++ stride = (w * 4 + 3) & (~3); ++ size_yrgb = stride*h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_RGB_888 : ++ stride = (w * 3 + 3) & (~3); ++ size_yrgb = stride*h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_BGRA_8888 : ++ size_yrgb = w*h*4; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_RGB_565 : ++ stride = (w*2 + 3) & (~3); ++ size_yrgb = stride * h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_RGBA_5551 : ++ stride = (w*2 + 3) & (~3); ++ size_yrgb = stride * h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_RGBA_4444 : ++ stride = (w*2 + 3) & (~3); ++ size_yrgb = stride * h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ case RK_FORMAT_BGR_888 : ++ stride = (w*3 + 3) & (~3); ++ size_yrgb = stride * h; ++ start = yrgb_addr >> PAGE_SHIFT; ++ pageCount = (size_yrgb + PAGE_SIZE - 1) >> PAGE_SHIFT; ++ break; ++ ++ /* YUV FORMAT */ ++ case RK_FORMAT_YCbCr_422_SP : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = stride * h; ++ start = MIN(yrgb_addr, uv_addr); ++ ++ start >>= PAGE_SHIFT; ++ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ case RK_FORMAT_YCbCr_422_P : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = ((stride >> 1) * h); ++ size_v = ((stride >> 1) * h); ++ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); ++ start = start >> PAGE_SHIFT; ++ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ case RK_FORMAT_YCbCr_420_SP : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = (stride * (h >> 1)); ++ start = MIN(yrgb_addr, uv_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ case RK_FORMAT_YCbCr_420_P : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = ((stride >> 1) * (h >> 1)); ++ size_v = ((stride >> 1) * (h >> 1)); ++ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ ++ case RK_FORMAT_YCrCb_422_SP : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = stride * h; ++ start = MIN(yrgb_addr, uv_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ case RK_FORMAT_YCrCb_422_P : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = ((stride >> 1) * h); ++ size_v = ((stride >> 1) * h); ++ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ ++ case RK_FORMAT_YCrCb_420_SP : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = (stride * (h >> 1)); ++ start = MIN(yrgb_addr, uv_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ case RK_FORMAT_YCrCb_420_P : ++ stride = (w + 3) & (~3); ++ size_yrgb = stride * h; ++ size_uv = ((stride >> 1) * (h >> 1)); ++ size_v = ((stride >> 1) * (h >> 1)); ++ start = MIN(MIN(yrgb_addr, uv_addr), v_addr); ++ start >>= PAGE_SHIFT; ++ end = MAX(MAX((yrgb_addr + size_yrgb), (uv_addr + size_uv)), (v_addr + size_v)); ++ end = (end + (PAGE_SIZE - 1)) >> PAGE_SHIFT; ++ pageCount = end - start; ++ break; ++ #if 0 ++ case RK_FORMAT_BPP1 : ++ break; ++ case RK_FORMAT_BPP2 : ++ break; ++ case RK_FORMAT_BPP4 : ++ break; ++ case RK_FORMAT_BPP8 : ++ break; ++ #endif ++ default : ++ pageCount = 0; ++ start = 0; ++ break; ++ } ++ ++ *StartAddr = start; ++ return pageCount; ++} ++ +#if RGA_DEBUGFS +static int rga_usermemory_cheeck(struct page **pages, u32 w, u32 h, u32 format, int flag) +{ @@ -1842733,85 +1842733,85 @@ index 000000000..32a99d53b +} +#endif + -+static int rga_MapUserMemory(struct page **pages, -+ uint32_t *pageTable, -+ unsigned long Memory, -+ uint32_t pageCount) -+{ -+ int32_t result; -+ uint32_t i; -+ uint32_t status; -+ unsigned long Address; -+ -+ status = 0; -+ Address = 0; -+ -+ do { ++static int rga_MapUserMemory(struct page **pages, ++ uint32_t *pageTable, ++ unsigned long Memory, ++ uint32_t pageCount) ++{ ++ int32_t result; ++ uint32_t i; ++ uint32_t status; ++ unsigned long Address; ++ ++ status = 0; ++ Address = 0; ++ ++ do { + rga_current_mm_read_lock(current->mm); + + result = rga_get_user_pages(pages, Memory, pageCount, 1, current->mm); + + rga_current_mm_read_unlock(current->mm); -+ -+ #if 0 -+ if(result <= 0 || result < pageCount) -+ { -+ status = 0; -+ -+ for(i=0; i0) { ++ ++ #if 0 ++ if(result <= 0 || result < pageCount) ++ { ++ status = 0; ++ ++ for(i=0; i0) { + rga_current_mm_read_lock(current->mm); + -+ for (i = 0; i < result; i++) -+ put_page(pages[i]); ++ for (i = 0; i < result; i++) ++ put_page(pages[i]); + + rga_current_mm_read_unlock(current->mm); -+ } -+ -+ for(i=0; imm, (Memory + i) << PAGE_SHIFT); -+ -+ if (vma)//&& (vma->vm_flags & VM_PFNMAP) ) -+ { -+ do -+ { -+ pte_t * pte; -+ spinlock_t * ptl; -+ unsigned long pfn; ++ } ++ ++ for(i=0; imm, (Memory + i) << PAGE_SHIFT); ++ ++ if (vma)//&& (vma->vm_flags & VM_PFNMAP) ) ++ { ++ do ++ { ++ pte_t * pte; ++ spinlock_t * ptl; ++ unsigned long pfn; + pgd_t * pgd; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + p4d_t * p4d; +#endif -+ pud_t * pud; -+ -+ pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); -+ -+ if(pgd_val(*pgd) == 0) -+ { -+ //printk("rga pgd value is zero \n"); -+ break; -+ } -+ ++ pud_t * pud; ++ ++ pgd = pgd_offset(current->mm, (Memory + i) << PAGE_SHIFT); ++ ++ if(pgd_val(*pgd) == 0) ++ { ++ //printk("rga pgd value is zero \n"); ++ break; ++ } ++ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) + /* In the four-level page table, it will do nothing and return pgd. */ + p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT); @@ -1842826,211 +1842826,211 @@ index 000000000..32a99d53b +#else + pud = pud_offset(pgd, (Memory + i) << PAGE_SHIFT); +#endif -+ if (pud) -+ { -+ pmd_t * pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); -+ if (pmd) -+ { -+ pte = pte_offset_map_lock(current->mm, pmd, (Memory + i) << PAGE_SHIFT, &ptl); -+ if (!pte) -+ { -+ pte_unmap_unlock(pte, ptl); -+ break; -+ } -+ } -+ else -+ { -+ break; -+ } -+ } -+ else -+ { -+ break; -+ } -+ -+ pfn = pte_pfn(*pte); -+ Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK)); -+ pte_unmap_unlock(pte, ptl); -+ } -+ while (0); -+ -+ pageTable[i] = Address; -+ } -+ else -+ { -+ status = RGA_OUT_OF_RESOURCES; -+ break; -+ } -+ } -+ -+ return status; -+ } -+ #endif -+ -+ /* Fill the page table. */ -+ for(i=0; imm, pmd, (Memory + i) << PAGE_SHIFT, &ptl); ++ if (!pte) ++ { ++ pte_unmap_unlock(pte, ptl); ++ break; ++ } ++ } ++ else ++ { ++ break; ++ } ++ } ++ else ++ { ++ break; ++ } ++ ++ pfn = pte_pfn(*pte); ++ Address = ((pfn << PAGE_SHIFT) | (((unsigned long)((Memory + i) << PAGE_SHIFT)) & ~PAGE_MASK)); ++ pte_unmap_unlock(pte, ptl); ++ } ++ while (0); ++ ++ pageTable[i] = Address; ++ } ++ else ++ { ++ status = RGA_OUT_OF_RESOURCES; ++ break; ++ } ++ } ++ ++ return status; ++ } ++ #endif ++ ++ /* Fill the page table. */ ++ for(i=0; imm); + -+ for (i = 0; i < result; i++) -+ put_page(pages[i]); ++ for (i = 0; i < result; i++) ++ put_page(pages[i]); + + rga_current_mm_read_unlock(current->mm); -+ -+ return 0; -+ } -+ while(0); -+ -+ return status; -+} -+ -+static int rga_MapION(struct sg_table *sg, -+ uint32_t *Memory, -+ int32_t pageCount, -+ uint32_t offset) -+{ -+ uint32_t i; -+ uint32_t status; -+ unsigned long Address; -+ uint32_t mapped_size = 0; -+ uint32_t len = 0; -+ struct scatterlist *sgl = sg->sgl; -+ uint32_t sg_num = 0; -+ -+ status = 0; -+ Address = 0; -+ offset = offset >> PAGE_SHIFT; -+ if (offset != 0) { -+ do { -+ len += (sg_dma_len(sgl) >> PAGE_SHIFT); -+ if (len == offset) { -+ sg_num += 1; -+ break; -+ } -+ else { -+ if (len > offset) -+ break; -+ } -+ sg_num += 1; -+ } -+ while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); -+ -+ sgl = sg->sgl; -+ len = 0; -+ do { -+ len += (sg_dma_len(sgl) >> PAGE_SHIFT); -+ sgl = sg_next(sgl); -+ } -+ while(--sg_num); -+ -+ offset -= len; -+ -+ len = sg_dma_len(sgl) >> PAGE_SHIFT; -+ Address = sg_phys(sgl); -+ Address += offset; -+ -+ for(i=offset; i> PAGE_SHIFT; -+ Address = sg_phys(sgl); -+ -+ for(i=0; inents)); -+ } -+ else { -+ do { -+ len = sg_dma_len(sgl) >> PAGE_SHIFT; -+ Address = sg_phys(sgl); -+ for(i=0; inents)); -+ } -+ return 0; -+} -+ -+ -+static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int SrcMemSize, DstMemSize; -+ unsigned long SrcStart, DstStart; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; -+ int ret; -+ int status; -+ uint32_t uv_size, v_size; -+ -+ struct page **pages = NULL; -+ -+ MMU_Base = NULL; -+ -+ SrcMemSize = 0; -+ DstMemSize = 0; -+ -+ do { -+ /* cal src buf mmu info */ -+ SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, -+ req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset, -+ &SrcStart); -+ if(SrcMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ /* cal dst buf mmu info */ -+ -+ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, -+ req->dst.format, req->dst.vir_w, req->dst.vir_h, -+ &DstStart); -+ if(DstMemSize == 0) -+ return -EINVAL; -+ -+ /* Cal out the needed mem size */ -+ SrcMemSize = (SrcMemSize + 15) & (~15); -+ DstMemSize = (DstMemSize + 15) & (~15); -+ AllSize = SrcMemSize + DstMemSize; -+ -+ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { -+ pr_err("RGA Get MMU mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ mutex_lock(&rga_service.lock); -+ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ mutex_unlock(&rga_service.lock); -+ -+ pages = rga_mmu_buf.pages; -+ -+ if((req->mmu_info.mmu_flag >> 8) & 1) { -+ if (req->sg_src) { -+ ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag); -+ } -+ else { -+ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); -+ if (ret < 0) { -+ pr_err("rga map src memory failed\n"); -+ status = ret; -+ break; ++ ++ return 0; ++ } ++ while(0); ++ ++ return status; ++} ++ ++static int rga_MapION(struct sg_table *sg, ++ uint32_t *Memory, ++ int32_t pageCount, ++ uint32_t offset) ++{ ++ uint32_t i; ++ uint32_t status; ++ unsigned long Address; ++ uint32_t mapped_size = 0; ++ uint32_t len = 0; ++ struct scatterlist *sgl = sg->sgl; ++ uint32_t sg_num = 0; ++ ++ status = 0; ++ Address = 0; ++ offset = offset >> PAGE_SHIFT; ++ if (offset != 0) { ++ do { ++ len += (sg_dma_len(sgl) >> PAGE_SHIFT); ++ if (len == offset) { ++ sg_num += 1; ++ break; ++ } ++ else { ++ if (len > offset) ++ break; ++ } ++ sg_num += 1; ++ } ++ while((sgl = sg_next(sgl)) && (mapped_size < pageCount) && (sg_num < sg->nents)); ++ ++ sgl = sg->sgl; ++ len = 0; ++ do { ++ len += (sg_dma_len(sgl) >> PAGE_SHIFT); ++ sgl = sg_next(sgl); ++ } ++ while(--sg_num); ++ ++ offset -= len; ++ ++ len = sg_dma_len(sgl) >> PAGE_SHIFT; ++ Address = sg_phys(sgl); ++ Address += offset; ++ ++ for(i=offset; i> PAGE_SHIFT; ++ Address = sg_phys(sgl); ++ ++ for(i=0; inents)); ++ } ++ else { ++ do { ++ len = sg_dma_len(sgl) >> PAGE_SHIFT; ++ Address = sg_phys(sgl); ++ for(i=0; inents)); ++ } ++ return 0; ++} ++ ++ ++static int rga_mmu_info_BitBlt_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int SrcMemSize, DstMemSize; ++ unsigned long SrcStart, DstStart; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; ++ int ret; ++ int status; ++ uint32_t uv_size, v_size; ++ ++ struct page **pages = NULL; ++ ++ MMU_Base = NULL; ++ ++ SrcMemSize = 0; ++ DstMemSize = 0; ++ ++ do { ++ /* cal src buf mmu info */ ++ SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, ++ req->src.format, req->src.vir_w, req->src.act_h + req->src.y_offset, ++ &SrcStart); ++ if(SrcMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ /* cal dst buf mmu info */ ++ ++ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, ++ req->dst.format, req->dst.vir_w, req->dst.vir_h, ++ &DstStart); ++ if(DstMemSize == 0) ++ return -EINVAL; ++ ++ /* Cal out the needed mem size */ ++ SrcMemSize = (SrcMemSize + 15) & (~15); ++ DstMemSize = (DstMemSize + 15) & (~15); ++ AllSize = SrcMemSize + DstMemSize; ++ ++ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { ++ pr_err("RGA Get MMU mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ mutex_lock(&rga_service.lock); ++ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ mutex_unlock(&rga_service.lock); ++ ++ pages = rga_mmu_buf.pages; ++ ++ if((req->mmu_info.mmu_flag >> 8) & 1) { ++ if (req->sg_src) { ++ ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize, req->line_draw_info.flag); ++ } ++ else { ++ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); ++ if (ret < 0) { ++ pr_err("rga map src memory failed\n"); ++ status = ret; ++ break; + } + +#if RGA_DEBUGFS @@ -1843038,665 +1843038,665 @@ index 000000000..32a99d53b + rga_usermemory_cheeck(&pages[0], req->src.vir_w, + req->src.vir_h, req->src.format, 1); +#endif -+ } -+ } -+ else { -+ MMU_p = MMU_Base; -+ -+ if(req->src.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { -+ for(i=0; immu_info.mmu_flag >> 10) & 1) { -+ if (req->sg_dst) { -+ ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); -+ } -+ else { -+ ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); -+ if (ret < 0) { -+ pr_err("rga map dst memory failed\n"); -+ status = ret; -+ break; -+ } ++ } ++ } ++ else { ++ MMU_p = MMU_Base; ++ ++ if(req->src.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { ++ for(i=0; immu_info.mmu_flag >> 10) & 1) { ++ if (req->sg_dst) { ++ ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); ++ } ++ else { ++ ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); ++ if (ret < 0) { ++ pr_err("rga map dst memory failed\n"); ++ status = ret; ++ break; ++ } + +#if RGA_DEBUGFS + if (RGA_CHECK_MODE) + rga_usermemory_cheeck(&pages[0], req->src.vir_w, + req->src.vir_h, req->src.format, 2); +#endif -+ } -+ } -+ else { -+ MMU_p = MMU_Base + SrcMemSize; -+ for(i=0; immu_info.base_addr = (unsigned long)MMU_Base_phys >> 2; -+ -+ uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ -+ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); -+ req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); -+ req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); -+ -+ uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ -+ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT); -+ req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); -+ -+ /* flush data to DDR */ ++ } ++ } ++ else { ++ MMU_p = MMU_Base + SrcMemSize; ++ for(i=0; immu_info.base_addr = (unsigned long)MMU_Base_phys >> 2; ++ ++ uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ ++ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); ++ req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); ++ req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); ++ ++ uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ ++ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | (SrcMemSize << PAGE_SHIFT); ++ req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); -+ -+ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); -+ reg->MMU_len = AllSize + 16; -+ -+ status = 0; -+ -+ return status; -+ } -+ while(0); -+ -+ return status; -+} -+ -+static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int SrcMemSize, DstMemSize, CMDMemSize; -+ unsigned long SrcStart, DstStart, CMDStart; -+ struct page **pages = NULL; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL; -+ uint32_t *MMU_p; ++ ++ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); ++ reg->MMU_len = AllSize + 16; ++ ++ status = 0; ++ ++ return status; ++ } ++ while(0); ++ ++ return status; ++} ++ ++static int rga_mmu_info_color_palette_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int SrcMemSize, DstMemSize, CMDMemSize; ++ unsigned long SrcStart, DstStart, CMDStart; ++ struct page **pages = NULL; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base = NULL, *MMU_Base_phys = NULL; ++ uint32_t *MMU_p; + int ret, status = 0; -+ uint32_t stride; -+ -+ uint8_t shift; -+ uint16_t sw, byte_num; -+ -+ shift = 3 - (req->palette_mode & 3); -+ sw = req->src.vir_w; -+ byte_num = sw >> shift; -+ stride = (byte_num + 3) & (~3); -+ -+ do { -+ SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); -+ if(SrcMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, -+ req->dst.format, req->dst.vir_w, req->dst.vir_h, -+ &DstStart); -+ if(DstMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); -+ if(CMDMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ SrcMemSize = (SrcMemSize + 15) & (~15); -+ DstMemSize = (DstMemSize + 15) & (~15); -+ CMDMemSize = (CMDMemSize + 15) & (~15); -+ -+ AllSize = SrcMemSize + DstMemSize + CMDMemSize; -+ -+ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { -+ pr_err("RGA Get MMU mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ mutex_lock(&rga_service.lock); -+ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ mutex_unlock(&rga_service.lock); -+ -+ pages = rga_mmu_buf.pages; -+ -+ /* map CMD addr */ -+ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) { -+ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); -+ if (ret < 0) { -+ pr_err("rga map src memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ else { -+ MMU_p = MMU_Base + CMDMemSize; -+ -+ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) { -+ ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize); -+ if (ret < 0) { -+ pr_err("rga map dst memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ else { -+ MMU_p = MMU_Base + CMDMemSize + SrcMemSize; -+ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base)>>2); -+ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); -+ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); -+ -+ /*record the malloc buf for the cmd end to release*/ -+ reg->MMU_base = MMU_Base; -+ -+ /* flush data to DDR */ ++ uint32_t stride; ++ ++ uint8_t shift; ++ uint16_t sw, byte_num; ++ ++ shift = 3 - (req->palette_mode & 3); ++ sw = req->src.vir_w; ++ byte_num = sw >> shift; ++ stride = (byte_num + 3) & (~3); ++ ++ do { ++ SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, stride, &SrcStart); ++ if(SrcMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, ++ req->dst.format, req->dst.vir_w, req->dst.vir_h, ++ &DstStart); ++ if(DstMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); ++ if(CMDMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ SrcMemSize = (SrcMemSize + 15) & (~15); ++ DstMemSize = (DstMemSize + 15) & (~15); ++ CMDMemSize = (CMDMemSize + 15) & (~15); ++ ++ AllSize = SrcMemSize + DstMemSize + CMDMemSize; ++ ++ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { ++ pr_err("RGA Get MMU mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ mutex_lock(&rga_service.lock); ++ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ mutex_unlock(&rga_service.lock); ++ ++ pages = rga_mmu_buf.pages; ++ ++ /* map CMD addr */ ++ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) { ++ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); ++ if (ret < 0) { ++ pr_err("rga map src memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ else { ++ MMU_p = MMU_Base + CMDMemSize; ++ ++ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) { ++ ret = rga_MapUserMemory(&pages[CMDMemSize + SrcMemSize], &MMU_Base[CMDMemSize + SrcMemSize], DstStart, DstMemSize); ++ if (ret < 0) { ++ pr_err("rga map dst memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ else { ++ MMU_p = MMU_Base + CMDMemSize + SrcMemSize; ++ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base)>>2); ++ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); ++ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((CMDMemSize + SrcMemSize) << PAGE_SHIFT); ++ ++ /*record the malloc buf for the cmd end to release*/ ++ reg->MMU_base = MMU_Base; ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); -+ -+ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); -+ reg->MMU_len = AllSize + 16; -+ ++ ++ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); ++ reg->MMU_len = AllSize + 16; ++ + return status; -+ -+ } -+ while(0); -+ -+ return 0; -+} -+ -+static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int DstMemSize; -+ unsigned long DstStart; -+ struct page **pages = NULL; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; -+ int ret; -+ int status; -+ -+ MMU_Base = NULL; -+ -+ do { -+ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, -+ req->dst.format, req->dst.vir_w, req->dst.vir_h, -+ &DstStart); -+ if(DstMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ AllSize = (DstMemSize + 15) & (~15); -+ -+ pages = rga_mmu_buf.pages; -+ -+ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { -+ pr_err("RGA Get MMU mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ mutex_lock(&rga_service.lock); -+ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ mutex_unlock(&rga_service.lock); -+ -+ if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) { -+ if (req->sg_dst) { -+ ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width); -+ } -+ else { -+ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize); -+ if (ret < 0) { -+ pr_err("rga map dst memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ } -+ else { -+ MMU_p = MMU_Base; -+ for(i=0; immu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); -+ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); -+ -+ /*record the malloc buf for the cmd end to release*/ -+ reg->MMU_base = MMU_Base; -+ -+ /* flush data to DDR */ ++ ++ } ++ while(0); ++ ++ return 0; ++} ++ ++static int rga_mmu_info_color_fill_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int DstMemSize; ++ unsigned long DstStart; ++ struct page **pages = NULL; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; ++ int ret; ++ int status; ++ ++ MMU_Base = NULL; ++ ++ do { ++ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, ++ req->dst.format, req->dst.vir_w, req->dst.vir_h, ++ &DstStart); ++ if(DstMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ AllSize = (DstMemSize + 15) & (~15); ++ ++ pages = rga_mmu_buf.pages; ++ ++ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { ++ pr_err("RGA Get MMU mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ mutex_lock(&rga_service.lock); ++ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ mutex_unlock(&rga_service.lock); ++ ++ if (req->dst.yrgb_addr < KERNEL_SPACE_VALID) { ++ if (req->sg_dst) { ++ ret = rga_MapION(req->sg_dst, &MMU_Base[0], DstMemSize, req->line_draw_info.line_width); ++ } ++ else { ++ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], DstStart, DstMemSize); ++ if (ret < 0) { ++ pr_err("rga map dst memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ } ++ else { ++ MMU_p = MMU_Base; ++ for(i=0; immu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); ++ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)); ++ ++ /*record the malloc buf for the cmd end to release*/ ++ reg->MMU_base = MMU_Base; ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); -+ -+ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); -+ reg->MMU_len = AllSize + 16; -+ -+ return 0; -+ } -+ while(0); -+ -+ return status; -+} -+ -+ -+static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ return 0; -+} -+ -+static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ return 0; -+} -+ -+ -+ -+static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int SrcMemSize, DstMemSize; -+ unsigned long SrcStart, DstStart; -+ struct page **pages = NULL; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; -+ int ret; -+ int status; -+ uint32_t uv_size, v_size; -+ -+ MMU_Base = NULL; -+ -+ do { -+ /* cal src buf mmu info */ -+ SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, -+ req->src.format, req->src.vir_w, req->src.vir_h, -+ &SrcStart); -+ if(SrcMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ /* cal dst buf mmu info */ -+ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, -+ req->dst.format, req->dst.vir_w, req->dst.vir_h, -+ &DstStart); -+ if(DstMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ SrcMemSize = (SrcMemSize + 15) & (~15); -+ DstMemSize = (DstMemSize + 15) & (~15); -+ -+ AllSize = SrcMemSize + DstMemSize; -+ -+ pages = rga_mmu_buf.pages; -+ -+ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { -+ pr_err("RGA Get MMU mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ mutex_lock(&rga_service.lock); -+ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); -+ mutex_unlock(&rga_service.lock); -+ -+ /* map src pages */ -+ if ((req->mmu_info.mmu_flag >> 8) & 1) { -+ if (req->sg_src) { -+ ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag); -+ } -+ else { -+ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); -+ if (ret < 0) { -+ pr_err("rga map src memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ } -+ else { -+ MMU_p = MMU_Base; -+ -+ for(i=0; immu_info.mmu_flag >> 10) & 1) { -+ if (req->sg_dst) { -+ ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); -+ } -+ else { -+ ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); -+ if (ret < 0) { -+ pr_err("rga map dst memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ } -+ else -+ { -+ /* kernel space */ -+ MMU_p = MMU_Base + SrcMemSize; -+ -+ if(req->dst.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { -+ for(i=0; immu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); -+ -+ uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ -+ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); -+ req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); -+ req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); -+ -+ uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; -+ -+ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT); -+ req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); -+ req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT); -+ -+ /*record the malloc buf for the cmd end to release*/ -+ reg->MMU_base = MMU_Base; -+ -+ /* flush data to DDR */ ++ ++ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); ++ reg->MMU_len = AllSize + 16; ++ ++ return 0; ++ } ++ while(0); ++ ++ return status; ++} ++ ++ ++static int rga_mmu_info_line_point_drawing_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ return 0; ++} ++ ++static int rga_mmu_info_blur_sharp_filter_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ return 0; ++} ++ ++ ++ ++static int rga_mmu_info_pre_scale_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int SrcMemSize, DstMemSize; ++ unsigned long SrcStart, DstStart; ++ struct page **pages = NULL; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base, *MMU_p, *MMU_Base_phys; ++ int ret; ++ int status; ++ uint32_t uv_size, v_size; ++ ++ MMU_Base = NULL; ++ ++ do { ++ /* cal src buf mmu info */ ++ SrcMemSize = rga_buf_size_cal(req->src.yrgb_addr, req->src.uv_addr, req->src.v_addr, ++ req->src.format, req->src.vir_w, req->src.vir_h, ++ &SrcStart); ++ if(SrcMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ /* cal dst buf mmu info */ ++ DstMemSize = rga_buf_size_cal(req->dst.yrgb_addr, req->dst.uv_addr, req->dst.v_addr, ++ req->dst.format, req->dst.vir_w, req->dst.vir_h, ++ &DstStart); ++ if(DstMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ SrcMemSize = (SrcMemSize + 15) & (~15); ++ DstMemSize = (DstMemSize + 15) & (~15); ++ ++ AllSize = SrcMemSize + DstMemSize; ++ ++ pages = rga_mmu_buf.pages; ++ ++ if (rga_mmu_buf_get_try(&rga_mmu_buf, AllSize + 16)) { ++ pr_err("RGA Get MMU mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ mutex_lock(&rga_service.lock); ++ MMU_Base = rga_mmu_buf.buf_virtual + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ MMU_Base_phys = rga_mmu_buf.buf + (rga_mmu_buf.front & (rga_mmu_buf.size - 1)); ++ mutex_unlock(&rga_service.lock); ++ ++ /* map src pages */ ++ if ((req->mmu_info.mmu_flag >> 8) & 1) { ++ if (req->sg_src) { ++ ret = rga_MapION(req->sg_src, &MMU_Base[0], SrcMemSize,req->line_draw_info.flag); ++ } ++ else { ++ ret = rga_MapUserMemory(&pages[0], &MMU_Base[0], SrcStart, SrcMemSize); ++ if (ret < 0) { ++ pr_err("rga map src memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ } ++ else { ++ MMU_p = MMU_Base; ++ ++ for(i=0; immu_info.mmu_flag >> 10) & 1) { ++ if (req->sg_dst) { ++ ret = rga_MapION(req->sg_dst, &MMU_Base[SrcMemSize], DstMemSize, req->line_draw_info.line_width); ++ } ++ else { ++ ret = rga_MapUserMemory(&pages[SrcMemSize], &MMU_Base[SrcMemSize], DstStart, DstMemSize); ++ if (ret < 0) { ++ pr_err("rga map dst memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ } ++ else ++ { ++ /* kernel space */ ++ MMU_p = MMU_Base + SrcMemSize; ++ ++ if(req->dst.yrgb_addr == (unsigned long)rga_service.pre_scale_buf) { ++ for(i=0; immu_info.base_addr = ((unsigned long)(MMU_Base_phys)>>2); ++ ++ uv_size = (req->src.uv_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ v_size = (req->src.v_addr - (SrcStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ ++ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)); ++ req->src.uv_addr = (req->src.uv_addr & (~PAGE_MASK)) | (uv_size << PAGE_SHIFT); ++ req->src.v_addr = (req->src.v_addr & (~PAGE_MASK)) | (v_size << PAGE_SHIFT); ++ ++ uv_size = (req->dst.uv_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ v_size = (req->dst.v_addr - (DstStart << PAGE_SHIFT)) >> PAGE_SHIFT; ++ ++ req->dst.yrgb_addr = (req->dst.yrgb_addr & (~PAGE_MASK)) | ((SrcMemSize) << PAGE_SHIFT); ++ req->dst.uv_addr = (req->dst.uv_addr & (~PAGE_MASK)) | ((SrcMemSize + uv_size) << PAGE_SHIFT); ++ req->dst.v_addr = (req->dst.v_addr & (~PAGE_MASK)) | ((SrcMemSize + v_size) << PAGE_SHIFT); ++ ++ /*record the malloc buf for the cmd end to release*/ ++ reg->MMU_base = MMU_Base; ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize + 1)); -+ -+ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); -+ reg->MMU_len = AllSize + 16; -+ -+ return 0; -+ } -+ while(0); -+ -+ return status; -+} -+ -+ -+static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int SrcMemSize, CMDMemSize; -+ unsigned long SrcStart, CMDStart; -+ struct page **pages = NULL; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base, *MMU_p; -+ int ret, status; -+ -+ MMU_Base = NULL; -+ -+ do { -+ /* cal src buf mmu info */ -+ SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart); -+ if(SrcMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ /* cal cmd buf mmu info */ -+ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); -+ if(CMDMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ AllSize = SrcMemSize + CMDMemSize; -+ -+ pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); -+ if(pages == NULL) { -+ pr_err("RGA MMU malloc pages mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); -+ if(pages == NULL) { -+ pr_err("RGA MMU malloc MMU_Base point failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) -+ { -+ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); -+ if (ret < 0) { -+ pr_err("rga map src memory failed\n"); -+ return -EINVAL; -+ } -+ } -+ else -+ { -+ MMU_p = MMU_Base + CMDMemSize; -+ -+ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); -+ -+ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); -+ -+ /*record the malloc buf for the cmd end to release*/ -+ reg->MMU_base = MMU_Base; -+ -+ /* flush data to DDR */ ++ ++ rga_mmu_buf_get(&rga_mmu_buf, AllSize + 16); ++ reg->MMU_len = AllSize + 16; ++ ++ return 0; ++ } ++ while(0); ++ ++ return status; ++} ++ ++ ++static int rga_mmu_info_update_palette_table_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int SrcMemSize, CMDMemSize; ++ unsigned long SrcStart, CMDStart; ++ struct page **pages = NULL; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base, *MMU_p; ++ int ret, status; ++ ++ MMU_Base = NULL; ++ ++ do { ++ /* cal src buf mmu info */ ++ SrcMemSize = rga_mem_size_cal(req->src.yrgb_addr, req->src.vir_w * req->src.vir_h, &SrcStart); ++ if(SrcMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ /* cal cmd buf mmu info */ ++ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); ++ if(CMDMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ AllSize = SrcMemSize + CMDMemSize; ++ ++ pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); ++ if(pages == NULL) { ++ pr_err("RGA MMU malloc pages mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ MMU_Base = kzalloc((AllSize + 1)* sizeof(uint32_t), GFP_KERNEL); ++ if(pages == NULL) { ++ pr_err("RGA MMU malloc MMU_Base point failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) ++ { ++ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); ++ if (ret < 0) { ++ pr_err("rga map src memory failed\n"); ++ return -EINVAL; ++ } ++ } ++ else ++ { ++ MMU_p = MMU_Base + CMDMemSize; ++ ++ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); ++ ++ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); ++ ++ /*record the malloc buf for the cmd end to release*/ ++ reg->MMU_base = MMU_Base; ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); -+ -+ -+ if (pages != NULL) { -+ /* Free the page table */ -+ kfree(pages); -+ } -+ -+ return 0; -+ } -+ while(0); -+ -+ if (pages != NULL) -+ kfree(pages); -+ -+ if (MMU_Base != NULL) -+ kfree(MMU_Base); -+ -+ return status; -+} -+ -+static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) -+{ -+ int SrcMemSize, CMDMemSize; -+ unsigned long SrcStart, CMDStart; -+ struct page **pages = NULL; -+ uint32_t i; -+ uint32_t AllSize; -+ uint32_t *MMU_Base, *MMU_p; -+ int ret, status; -+ -+ MMU_Base = MMU_p = 0; -+ -+ do -+ { -+ -+ /* cal src buf mmu info */ -+ SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart); -+ if(SrcMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ /* cal cmd buf mmu info */ -+ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); -+ if(CMDMemSize == 0) { -+ return -EINVAL; -+ } -+ -+ AllSize = SrcMemSize + CMDMemSize; -+ -+ pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); -+ if(pages == NULL) { -+ pr_err("RGA MMU malloc pages mem failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); -+ if(MMU_Base == NULL) { -+ pr_err("RGA MMU malloc MMU_Base point failed\n"); -+ status = RGA_MALLOC_ERROR; -+ break; -+ } -+ -+ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) -+ { -+ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); -+ if (ret < 0) { -+ pr_err("rga map src memory failed\n"); -+ status = ret; -+ break; -+ } -+ } -+ else -+ { -+ MMU_p = MMU_Base + CMDMemSize; -+ -+ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); -+ -+ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); -+ -+ /*record the malloc buf for the cmd end to release*/ -+ reg->MMU_base = MMU_Base; -+ -+ /* flush data to DDR */ ++ ++ ++ if (pages != NULL) { ++ /* Free the page table */ ++ kfree(pages); ++ } ++ ++ return 0; ++ } ++ while(0); ++ ++ if (pages != NULL) ++ kfree(pages); ++ ++ if (MMU_Base != NULL) ++ kfree(MMU_Base); ++ ++ return status; ++} ++ ++static int rga_mmu_info_update_patten_buff_mode(struct rga_reg *reg, struct rga_req *req) ++{ ++ int SrcMemSize, CMDMemSize; ++ unsigned long SrcStart, CMDStart; ++ struct page **pages = NULL; ++ uint32_t i; ++ uint32_t AllSize; ++ uint32_t *MMU_Base, *MMU_p; ++ int ret, status; ++ ++ MMU_Base = MMU_p = 0; ++ ++ do ++ { ++ ++ /* cal src buf mmu info */ ++ SrcMemSize = rga_mem_size_cal(req->pat.yrgb_addr, req->pat.vir_w * req->pat.vir_h * 4, &SrcStart); ++ if(SrcMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ /* cal cmd buf mmu info */ ++ CMDMemSize = rga_mem_size_cal((unsigned long)rga_service.cmd_buff, RGA_CMD_BUF_SIZE, &CMDStart); ++ if(CMDMemSize == 0) { ++ return -EINVAL; ++ } ++ ++ AllSize = SrcMemSize + CMDMemSize; ++ ++ pages = kzalloc(AllSize * sizeof(struct page *), GFP_KERNEL); ++ if(pages == NULL) { ++ pr_err("RGA MMU malloc pages mem failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ MMU_Base = kzalloc(AllSize * sizeof(uint32_t), GFP_KERNEL); ++ if(MMU_Base == NULL) { ++ pr_err("RGA MMU malloc MMU_Base point failed\n"); ++ status = RGA_MALLOC_ERROR; ++ break; ++ } ++ ++ for(i=0; isrc.yrgb_addr < KERNEL_SPACE_VALID) ++ { ++ ret = rga_MapUserMemory(&pages[CMDMemSize], &MMU_Base[CMDMemSize], SrcStart, SrcMemSize); ++ if (ret < 0) { ++ pr_err("rga map src memory failed\n"); ++ status = ret; ++ break; ++ } ++ } ++ else ++ { ++ MMU_p = MMU_Base + CMDMemSize; ++ ++ for(i=0; immu_info.base_addr = (virt_to_phys(MMU_Base) >> 2); ++ ++ req->src.yrgb_addr = (req->src.yrgb_addr & (~PAGE_MASK)) | (CMDMemSize << PAGE_SHIFT); ++ ++ /*record the malloc buf for the cmd end to release*/ ++ reg->MMU_base = MMU_Base; ++ ++ /* flush data to DDR */ + rga_dma_flush_range(MMU_Base, (MMU_Base + AllSize)); -+ -+ if (pages != NULL) { -+ /* Free the page table */ -+ kfree(pages); -+ } -+ -+ return 0; -+ -+ } -+ while(0); -+ -+ if (pages != NULL) -+ kfree(pages); -+ -+ if (MMU_Base != NULL) -+ kfree(MMU_Base); -+ -+ return status; -+} -+ -+int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req) -+{ -+ int ret; -+ -+ switch (req->render_mode) { -+ case bitblt_mode : -+ ret = rga_mmu_info_BitBlt_mode(reg, req); -+ break; -+ case color_palette_mode : -+ ret = rga_mmu_info_color_palette_mode(reg, req); -+ break; -+ case color_fill_mode : -+ ret = rga_mmu_info_color_fill_mode(reg, req); -+ break; -+ case line_point_drawing_mode : -+ ret = rga_mmu_info_line_point_drawing_mode(reg, req); -+ break; -+ case blur_sharp_filter_mode : -+ ret = rga_mmu_info_blur_sharp_filter_mode(reg, req); -+ break; -+ case pre_scaling_mode : -+ ret = rga_mmu_info_pre_scale_mode(reg, req); -+ break; -+ case update_palette_table_mode : -+ ret = rga_mmu_info_update_palette_table_mode(reg, req); -+ break; -+ case update_patten_buff_mode : -+ ret = rga_mmu_info_update_patten_buff_mode(reg, req); -+ break; -+ default : -+ ret = -1; -+ break; -+ } -+ -+ return ret; -+} -+ ++ ++ if (pages != NULL) { ++ /* Free the page table */ ++ kfree(pages); ++ } ++ ++ return 0; ++ ++ } ++ while(0); ++ ++ if (pages != NULL) ++ kfree(pages); ++ ++ if (MMU_Base != NULL) ++ kfree(MMU_Base); ++ ++ return status; ++} ++ ++int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req) ++{ ++ int ret; ++ ++ switch (req->render_mode) { ++ case bitblt_mode : ++ ret = rga_mmu_info_BitBlt_mode(reg, req); ++ break; ++ case color_palette_mode : ++ ret = rga_mmu_info_color_palette_mode(reg, req); ++ break; ++ case color_fill_mode : ++ ret = rga_mmu_info_color_fill_mode(reg, req); ++ break; ++ case line_point_drawing_mode : ++ ret = rga_mmu_info_line_point_drawing_mode(reg, req); ++ break; ++ case blur_sharp_filter_mode : ++ ret = rga_mmu_info_blur_sharp_filter_mode(reg, req); ++ break; ++ case pre_scaling_mode : ++ ret = rga_mmu_info_pre_scale_mode(reg, req); ++ break; ++ case update_palette_table_mode : ++ ret = rga_mmu_info_update_palette_table_mode(reg, req); ++ break; ++ case update_patten_buff_mode : ++ ret = rga_mmu_info_update_patten_buff_mode(reg, req); ++ break; ++ default : ++ ret = -1; ++ break; ++ } ++ ++ return ret; ++} ++ diff --git a/drivers/video/rockchip/rga/rga_mmu_info.h b/drivers/video/rockchip/rga/rga_mmu_info.h new file mode 100644 index 000000000..d4226cc16 @@ -1843704,29 +1843704,29 @@ index 000000000..d4226cc16 +++ b/drivers/video/rockchip/rga/rga_mmu_info.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __RGA_MMU_INFO_H__ -+#define __RGA_MMU_INFO_H__ -+ ++#ifndef __RGA_MMU_INFO_H__ ++#define __RGA_MMU_INFO_H__ ++ +#include "rga.h" +#include "RGA_API.h" -+ -+#ifndef MIN -+#define MIN(X, Y) ((X)<(Y)?(X):(Y)) -+#endif -+ -+#ifndef MAX -+#define MAX(X, Y) ((X)>(Y)?(X):(Y)) -+#endif ++ ++#ifndef MIN ++#define MIN(X, Y) ((X)<(Y)?(X):(Y)) ++#endif ++ ++#ifndef MAX ++#define MAX(X, Y) ((X)>(Y)?(X):(Y)) ++#endif + +extern struct rga_drvdata *rga_drvdata; + +void rga_dma_flush_range(void *pstart, void *pend); -+int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req); -+ -+ -+#endif -+ -+ ++int rga_set_mmu_info(struct rga_reg *reg, struct rga_req *req); ++ ++ ++#endif ++ ++ diff --git a/drivers/video/rockchip/rga/rga_reg_info.c b/drivers/video/rockchip/rga/rga_reg_info.c new file mode 100644 index 000000000..94a6305b8 @@ -1843734,710 +1843734,710 @@ index 000000000..94a6305b8 +++ b/drivers/video/rockchip/rga/rga_reg_info.c @@ -0,0 +1,1587 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+ -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+//#include -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++//#include ++//#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include +#include -+ -+#include "rga_reg_info.h" -+#include "rga_rop.h" -+#include "rga.h" -+ -+ -+/************************************************************* -+Func: -+ RGA_pixel_width_init -+Description: -+ select pixel_width form data format -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+unsigned char -+RGA_pixel_width_init(unsigned int format) -+{ -+ unsigned char pixel_width; -+ -+ pixel_width = 0; -+ -+ switch(format) -+ { -+ /* RGB FORMAT */ -+ case RK_FORMAT_RGBA_8888 : pixel_width = 4; break; -+ case RK_FORMAT_RGBX_8888 : pixel_width = 4; break; -+ case RK_FORMAT_RGB_888 : pixel_width = 3; break; -+ case RK_FORMAT_BGRA_8888 : pixel_width = 4; break; -+ case RK_FORMAT_RGB_565 : pixel_width = 2; break; -+ case RK_FORMAT_RGBA_5551 : pixel_width = 2; break; -+ case RK_FORMAT_RGBA_4444 : pixel_width = 2; break; -+ case RK_FORMAT_BGR_888 : pixel_width = 3; break; -+ -+ /* YUV FORMAT */ -+ case RK_FORMAT_YCbCr_422_SP : pixel_width = 1; break; -+ case RK_FORMAT_YCbCr_422_P : pixel_width = 1; break; -+ case RK_FORMAT_YCbCr_420_SP : pixel_width = 1; break; -+ case RK_FORMAT_YCbCr_420_P : pixel_width = 1; break; -+ case RK_FORMAT_YCrCb_422_SP : pixel_width = 1; break; -+ case RK_FORMAT_YCrCb_422_P : pixel_width = 1; break; -+ case RK_FORMAT_YCrCb_420_SP : pixel_width = 1; break; -+ case RK_FORMAT_YCrCb_420_P : pixel_width = 1; break; -+ //case default : pixel_width = 0; break; -+ } -+ -+ return pixel_width; -+} -+ -+/************************************************************* -+Func: -+ dst_ctrl_cal -+Description: -+ calculate dst act window position / width / height -+ and set the tile struct -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+static void -+dst_ctrl_cal(const struct rga_req *msg, TILE_INFO *tile) -+{ -+ u32 width = msg->dst.act_w; -+ u32 height = msg->dst.act_h; -+ s32 xoff = msg->dst.x_offset; -+ s32 yoff = msg->dst.y_offset; -+ -+ s32 x0, y0, x1, y1, x2, y2; -+ s32 x00,y00,x10,y10,x20,y20; -+ s32 xx, xy, yx, yy; -+ s32 pos[8]; -+ -+ s32 xmax, xmin, ymax, ymin; -+ -+ s32 sina = msg->sina; /* 16.16 */ -+ s32 cosa = msg->cosa; /* 16.16 */ -+ -+ xmax = xmin = ymax = ymin = 0; -+ -+ if((msg->rotate_mode == 0)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) -+ { -+ pos[0] = xoff; -+ pos[1] = yoff; -+ -+ pos[2] = xoff; -+ pos[3] = yoff + height - 1; -+ -+ pos[4] = xoff + width - 1; -+ pos[5] = yoff + height - 1; -+ -+ pos[6] = xoff + width - 1; -+ pos[7] = yoff; -+ -+ xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); -+ xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); -+ -+ ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); -+ ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); -+ -+ //printk("xmax = %d, xmin = %d, ymin = %d, ymax = %d\n", xmax, xmin, ymin, ymax); -+ } -+ else if(msg->rotate_mode == 1) -+ { -+ if((sina == 0) || (cosa == 0)) -+ { -+ if((sina == 0) && (cosa == -65536)) -+ { -+ /* 180 */ -+ pos[0] = xoff - width + 1; -+ pos[1] = yoff - height + 1; -+ -+ pos[2] = xoff - width + 1; -+ pos[3] = yoff; -+ -+ pos[4] = xoff; -+ pos[5] = yoff; -+ -+ pos[6] = xoff; -+ pos[7] = yoff - height + 1; -+ } -+ else if((cosa == 0)&&(sina == 65536)) -+ { -+ /* 90 */ -+ pos[0] = xoff - height + 1; -+ pos[1] = yoff; -+ -+ pos[2] = xoff - height + 1; -+ pos[3] = yoff + width - 1; -+ -+ pos[4] = xoff; -+ pos[5] = yoff + width - 1; -+ -+ pos[6] = xoff; -+ pos[7] = yoff; -+ } -+ else if((cosa == 0)&&(sina == -65536)) -+ { -+ /* 270 */ -+ pos[0] = xoff; -+ pos[1] = yoff - width + 1; -+ -+ pos[2] = xoff; -+ pos[3] = yoff; -+ -+ pos[4] = xoff + height - 1; -+ pos[5] = yoff; -+ -+ pos[6] = xoff + height - 1; -+ pos[7] = yoff - width + 1; -+ } -+ else -+ { -+ /* 0 */ -+ pos[0] = xoff; -+ pos[1] = yoff; -+ -+ pos[2] = xoff; -+ pos[3] = yoff + height - 1; -+ -+ pos[4] = xoff + width - 1; -+ pos[5] = yoff + height - 1; -+ -+ pos[6] = xoff + width - 1; -+ pos[7] = yoff; -+ } -+ -+ xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); -+ xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); -+ -+ ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); -+ ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); -+ } -+ else -+ { -+ xx = msg->cosa; -+ xy = msg->sina; -+ yx = xy; -+ yy = xx; -+ -+ x0 = width + xoff; -+ y0 = yoff; -+ -+ x1 = xoff; -+ y1 = height + yoff; -+ -+ x2 = width + xoff; -+ y2 = height + yoff; -+ -+ pos[0] = xoff; -+ pos[1] = yoff; -+ -+ pos[2] = x00 = (((x0 - xoff)*xx - (y0 - yoff)*xy)>>16) + xoff; -+ pos[3] = y00 = (((x0 - xoff)*yx + (y0 - yoff)*yy)>>16) + yoff; -+ -+ pos[4] = x10 = (((x1 - xoff)*xx - (y1 - yoff)*xy)>>16) + xoff; -+ pos[5] = y10 = (((x1 - xoff)*yx + (y1 - yoff)*yy)>>16) + yoff; -+ -+ pos[6] = x20 = (((x2 - xoff)*xx - (y2 - yoff)*xy)>>16) + xoff; -+ pos[7] = y20 = (((x2 - xoff)*yx + (y2 - yoff)*yy)>>16) + yoff; -+ -+ xmax = MAX(MAX(MAX(x00, xoff), x10), x20) + 2; -+ xmin = MIN(MIN(MIN(x00, xoff), x10), x20) - 1; -+ -+ ymax = MAX(MAX(MAX(y00, yoff), y10), y20) + 2; -+ ymin = MIN(MIN(MIN(y00, yoff), y10), y20) - 1; -+ -+ xmax = MIN(xmax, msg->clip.xmax); -+ xmin = MAX(xmin, msg->clip.xmin); -+ -+ ymax = MIN(ymax, msg->clip.ymax); -+ ymin = MAX(ymin, msg->clip.ymin); -+ -+ //printk("xmin = %d, xmax = %d, ymin = %d, ymax = %d\n", xmin, xmax, ymin, ymax); -+ } -+ } -+ -+ if ((xmax < xmin) || (ymax < ymin)) { -+ xmin = xmax; -+ ymin = ymax; -+ } -+ -+ if ((xmin >= msg->dst.vir_w)||(xmax < 0)||(ymin >= msg->dst.vir_h)||(ymax < 0)) { -+ xmin = xmax = ymin = ymax = 0; -+ } -+ -+ //printk("xmin = %d, xmax = %d, ymin = %d, ymax = %d\n", xmin, xmax, ymin, ymax); -+ -+ tile->dst_ctrl.w = (xmax - xmin); -+ tile->dst_ctrl.h = (ymax - ymin); -+ tile->dst_ctrl.x_off = xmin; -+ tile->dst_ctrl.y_off = ymin; -+ -+ //printk("tile->dst_ctrl.w = %x, tile->dst_ctrl.h = %x\n", tile->dst_ctrl.w, tile->dst_ctrl.h); -+ -+ tile->tile_x_num = (xmax - xmin + 1 + 7)>>3; -+ tile->tile_y_num = (ymax - ymin + 1 + 7)>>3; -+ -+ tile->dst_x_tmp = xmin - msg->dst.x_offset; -+ tile->dst_y_tmp = ymin - msg->dst.y_offset; -+} -+ -+/************************************************************* -+Func: -+ src_tile_info_cal -+Description: -+ calculate src remap window position / width / height -+ and set the tile struct -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+src_tile_info_cal(const struct rga_req *msg, TILE_INFO *tile) -+{ -+ s32 x0, x1, x2, x3, y0, y1, y2, y3; -+ -+ int64_t xx, xy, yx, yy; -+ -+ int64_t pos[8]; -+ int64_t epos[8]; -+ -+ int64_t x_dx, x_dy, y_dx, y_dy; -+ int64_t x_temp_start, y_temp_start; -+ int64_t xmax, xmin, ymax, ymin; -+ -+ int64_t t_xoff, t_yoff; -+ -+ xx = tile->matrix[0]; /* 32.32 */ -+ xy = tile->matrix[1]; /* 32.32 */ -+ yx = tile->matrix[2]; /* 32.32 */ -+ yy = tile->matrix[3]; /* 32.32 */ -+ -+ if(msg->rotate_mode == 1) -+ { -+ x0 = tile->dst_x_tmp; -+ y0 = tile->dst_y_tmp; -+ -+ x1 = x0; -+ y1 = y0 + 8; -+ -+ x2 = x0 + 8; -+ y2 = y0 + 8; -+ -+ x3 = x0 + 8; -+ y3 = y0; -+ -+ pos[0] = (x0*xx + y0*yx); -+ pos[1] = (x0*xy + y0*yy); -+ -+ pos[2] = (x1*xx + y1*yx); -+ pos[3] = (x1*xy + y1*yy); -+ -+ pos[4] = (x2*xx + y2*yx); -+ pos[5] = (x2*xy + y2*yy); -+ -+ pos[6] = (x3*xx + y3*yx); -+ pos[7] = (x3*xy + y3*yy); -+ -+ y1 = y0 + 7; -+ x2 = x0 + 7; -+ y2 = y0 + 7; -+ x3 = x0 + 7; -+ -+ epos[0] = pos[0]; -+ epos[1] = pos[1]; -+ -+ epos[2] = (x1*xx + y1*yx); -+ epos[3] = (x1*xy + y1*yy); -+ -+ epos[4] = (x2*xx + y2*yx); -+ epos[5] = (x2*xy + y2*yy); -+ -+ epos[6] = (x3*xx + y3*yx); -+ epos[7] = (x3*xy + y3*yy); -+ -+ x_dx = pos[6] - pos[0]; -+ x_dy = pos[7] - pos[1]; -+ -+ y_dx = pos[2] - pos[0]; -+ y_dy = pos[3] - pos[1]; -+ -+ tile->x_dx = (s32)(x_dx >> 22 ); -+ tile->x_dy = (s32)(x_dy >> 22 ); -+ tile->y_dx = (s32)(y_dx >> 22 ); -+ tile->y_dy = (s32)(y_dy >> 22 ); -+ -+ x_temp_start = x0*xx + y0*yx; -+ y_temp_start = x0*xy + y0*yy; -+ -+ xmax = (MAX(MAX(MAX(epos[0], epos[2]), epos[4]), epos[6])); -+ xmin = (MIN(MIN(MIN(epos[0], epos[2]), epos[4]), epos[6])); -+ -+ ymax = (MAX(MAX(MAX(epos[1], epos[3]), epos[5]), epos[7])); -+ ymin = (MIN(MIN(MIN(epos[1], epos[3]), epos[5]), epos[7])); -+ -+ t_xoff = (x_temp_start - xmin)>>18; -+ t_yoff = (y_temp_start - ymin)>>18; -+ -+ tile->tile_xoff = (s32)t_xoff; -+ tile->tile_yoff = (s32)t_yoff; -+ -+ tile->tile_w = (u16)((xmax - xmin)>>21); //.11 -+ tile->tile_h = (u16)((ymax - ymin)>>21); //.11 -+ -+ tile->tile_start_x_coor = (s16)(xmin>>29); //.3 -+ tile->tile_start_y_coor = (s16)(ymin>>29); //.3 -+ } -+ else if (msg->rotate_mode == 2) -+ { -+ tile->x_dx = (s32)((8*xx)>>22); -+ tile->x_dy = 0; -+ tile->y_dx = 0; -+ tile->y_dy = (s32)((8*yy)>>22); -+ -+ tile->tile_w = ABS((s32)((7*xx)>>21)); -+ tile->tile_h = ABS((s32)((7*yy)>>21)); -+ -+ tile->tile_xoff = ABS((s32)((7*xx)>>18)); -+ tile->tile_yoff = 0; -+ -+ tile->tile_start_x_coor = (((msg->src.act_w - 1)<<11) - (tile->tile_w))>>8; -+ tile->tile_start_y_coor = 0; -+ } -+ else if (msg->rotate_mode == 3) -+ { -+ tile->x_dx = (s32)((8*xx)>>22); -+ tile->x_dy = 0; -+ tile->y_dx = 0; -+ tile->y_dy = (s32)((8*yy)>>22); -+ -+ tile->tile_w = ABS((s32)((7*xx)>>21)); -+ tile->tile_h = ABS((s32)((7*yy)>>21)); -+ -+ tile->tile_xoff = 0; -+ tile->tile_yoff = ABS((s32)((7*yy)>>18)); -+ -+ tile->tile_start_x_coor = 0; -+ tile->tile_start_y_coor = (((msg->src.act_h - 1)<<11) - (tile->tile_h))>>8; -+ } -+ -+ if ((msg->scale_mode == 2)||(msg->alpha_rop_flag >> 7)) -+ { -+ tile->tile_start_x_coor -= (1<<3); -+ tile->tile_start_y_coor -= (1<<3); -+ tile->tile_w += (2 << 11); -+ tile->tile_h += (2 << 11); -+ tile->tile_xoff += (1<<14); -+ tile->tile_yoff += (1<<14); -+ } -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_mode_ctrl -+Description: -+ fill mode ctrl reg info -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+RGA_set_mode_ctrl(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_MODE_CTL; -+ u32 reg = 0; -+ -+ u8 src_rgb_pack = 0; -+ u8 src_format = 0; -+ u8 src_rb_swp = 0; -+ u8 src_a_swp = 0; -+ u8 src_cbcr_swp = 0; -+ -+ u8 dst_rgb_pack = 0; -+ u8 dst_format = 0; -+ u8 dst_rb_swp = 0; -+ u8 dst_a_swp = 0; -+ -+ bRGA_MODE_CTL = (u32 *)(base + RGA_MODE_CTRL_OFFSET); -+ -+ reg = ((reg & (~m_RGA_MODE_CTRL_2D_RENDER_MODE)) | (s_RGA_MODE_CTRL_2D_RENDER_MODE(msg->render_mode))); -+ -+ /* src info set */ -+ -+ if (msg->render_mode == color_palette_mode || msg->render_mode == update_palette_table_mode) -+ { -+ src_format = 0x10 | (msg->palette_mode & 3); -+ } -+ else -+ { -+ switch (msg->src.format) -+ { -+ case RK_FORMAT_RGBA_8888 : src_format = 0x0; break; -+ case RK_FORMAT_RGBA_4444 : src_format = 0x3; break; -+ case RK_FORMAT_RGBA_5551 : src_format = 0x2; break; -+ case RK_FORMAT_BGRA_8888 : src_format = 0x0; src_rb_swp = 0x1; break; -+ case RK_FORMAT_RGBX_8888 : src_format = 0x0; break; -+ case RK_FORMAT_RGB_565 : src_format = 0x1; break; -+ case RK_FORMAT_RGB_888 : src_format = 0x0; src_rgb_pack = 1; break; -+ case RK_FORMAT_BGR_888 : src_format = 0x0; src_rgb_pack = 1; src_rb_swp = 1; break; -+ -+ case RK_FORMAT_YCbCr_422_SP : src_format = 0x4; break; -+ case RK_FORMAT_YCbCr_422_P : src_format = 0x5; break; -+ case RK_FORMAT_YCbCr_420_SP : src_format = 0x6; break; -+ case RK_FORMAT_YCbCr_420_P : src_format = 0x7; break; -+ -+ case RK_FORMAT_YCrCb_422_SP : src_format = 0x4; src_cbcr_swp = 1; break; -+ case RK_FORMAT_YCrCb_422_P : src_format = 0x5; src_cbcr_swp = 1; break; -+ case RK_FORMAT_YCrCb_420_SP : src_format = 0x6; src_cbcr_swp = 1; break; -+ case RK_FORMAT_YCrCb_420_P : src_format = 0x7; src_cbcr_swp = 1; break; -+ } -+ } -+ -+ src_a_swp = msg->src.alpha_swap & 1; -+ -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RGB_PACK)) | (s_RGA_MODE_CTRL_SRC_RGB_PACK(src_rgb_pack))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_FORMAT)) | (s_RGA_MODE_CTRL_SRC_FORMAT(src_format))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RB_SWAP)) | (s_RGA_MODE_CTRL_SRC_RB_SWAP(src_rb_swp))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(src_a_swp))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE )) | (s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE (src_cbcr_swp))); -+ -+ -+ /* YUV2RGB MODE */ -+ reg = ((reg & (~m_RGA_MODE_CTRL_YUV2RGB_CON_MODE)) | (s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(msg->yuv2rgb_mode))); -+ -+ /* ROTATE MODE */ -+ reg = ((reg & (~m_RGA_MODE_CTRL_ROTATE_MODE)) | (s_RGA_MODE_CTRL_ROTATE_MODE(msg->rotate_mode))); -+ -+ /* SCALE MODE */ -+ reg = ((reg & (~m_RGA_MODE_CTRL_SCALE_MODE)) | (s_RGA_MODE_CTRL_SCALE_MODE(msg->scale_mode))); -+ -+ /* COLOR FILL MODE */ -+ reg = ((reg & (~m_RGA_MODE_CTRL_PAT_SEL)) | (s_RGA_MODE_CTRL_PAT_SEL(msg->color_fill_mode))); -+ -+ -+ if ((msg->render_mode == update_palette_table_mode)||(msg->render_mode == update_patten_buff_mode)) -+ { -+ dst_format = msg->pat.format; -+ } -+ else -+ { -+ dst_format = (u8)msg->dst.format; -+ } -+ -+ /* dst info set */ -+ switch (dst_format) -+ { -+ case RK_FORMAT_BGRA_8888 : dst_format = 0x0; dst_rb_swp = 0x1; break; -+ case RK_FORMAT_RGBA_4444 : dst_format = 0x3; break; -+ case RK_FORMAT_RGBA_5551 : dst_format = 0x2; break; -+ case RK_FORMAT_RGBA_8888 : dst_format = 0x0; break; -+ case RK_FORMAT_RGB_565 : dst_format = 0x1; break; -+ case RK_FORMAT_RGB_888 : dst_format = 0x0; dst_rgb_pack = 0x1; break; -+ case RK_FORMAT_BGR_888 : dst_format = 0x0; dst_rgb_pack = 0x1; dst_rb_swp = 1; break; -+ case RK_FORMAT_RGBX_8888 : dst_format = 0x0; break; -+ } -+ -+ dst_a_swp = msg->dst.alpha_swap & 1; -+ -+ reg = ((reg & (~m_RGA_MODE_CTRL_DST_FORMAT)) | (s_RGA_MODE_CTRL_DST_FORMAT(dst_format))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_DST_RGB_PACK)) | (s_RGA_MODE_CTRL_DST_RGB_PACK(dst_rgb_pack))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_DST_RB_SWAP)) | (s_RGA_MODE_CTRL_DST_RB_SWAP(dst_rb_swp))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_DST_ALPHA_SWAP(dst_a_swp))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_LUT_ENDIAN_MODE)) | (s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(msg->endian_mode & 1))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_TRANS_MODE)) | (s_RGA_MODE_CTRL_SRC_TRANS_MODE(msg->src_trans_mode))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_ZERO_MODE_ENABLE)) | (s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(msg->alpha_rop_mode >> 4))); -+ reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_ENABLE)) | (s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(msg->alpha_rop_mode >> 5))); -+ -+ *bRGA_MODE_CTL = reg; -+ -+} -+ -+ -+ -+/************************************************************* -+Func: -+ RGA_set_src -+Description: -+ fill src relate reg info -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+RGA_set_src(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_SRC_VIR_INFO; -+ u32 *bRGA_SRC_ACT_INFO; -+ u32 *bRGA_SRC_Y_MST; -+ u32 *bRGA_SRC_CB_MST; -+ u32 *bRGA_SRC_CR_MST; -+ -+ s16 x_off, y_off, stride; -+ s16 uv_x_off, uv_y_off, uv_stride; -+ u32 pixel_width; -+ -+ uv_x_off = uv_y_off = uv_stride = 0; -+ -+ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); -+ bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); -+ bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); -+ bRGA_SRC_VIR_INFO = (u32 *)(base + RGA_SRC_VIR_INFO_OFFSET); -+ bRGA_SRC_ACT_INFO = (u32 *)(base + RGA_SRC_ACT_INFO_OFFSET); -+ -+ x_off = msg->src.x_offset; -+ y_off = msg->src.y_offset; -+ -+ pixel_width = RGA_pixel_width_init(msg->src.format); -+ -+ stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); -+ -+ switch(msg->src.format) -+ { -+ case RK_FORMAT_YCbCr_422_SP : -+ uv_stride = stride; -+ uv_x_off = x_off; -+ uv_y_off = y_off; -+ break; -+ case RK_FORMAT_YCbCr_422_P : -+ uv_stride = stride >> 1; -+ uv_x_off = x_off >> 1; -+ uv_y_off = y_off; -+ break; -+ case RK_FORMAT_YCbCr_420_SP : -+ uv_stride = stride; -+ uv_x_off = x_off; -+ uv_y_off = y_off >> 1; -+ break; -+ case RK_FORMAT_YCbCr_420_P : -+ uv_stride = stride >> 1; -+ uv_x_off = x_off >> 1; -+ uv_y_off = y_off >> 1; -+ break; -+ case RK_FORMAT_YCrCb_422_SP : -+ uv_stride = stride; -+ uv_x_off = x_off; -+ uv_y_off = y_off; -+ break; -+ case RK_FORMAT_YCrCb_422_P : -+ uv_stride = stride >> 1; -+ uv_x_off = x_off >> 1; -+ uv_y_off = y_off; -+ break; -+ case RK_FORMAT_YCrCb_420_SP : -+ uv_stride = stride; -+ uv_x_off = x_off; -+ uv_y_off = y_off >> 1; -+ break; -+ case RK_FORMAT_YCrCb_420_P : -+ uv_stride = stride >> 1; -+ uv_x_off = x_off >> 1; -+ uv_y_off = y_off >> 1; -+ break; -+ } -+ -+ -+ /* src addr set */ -+ *bRGA_SRC_Y_MST = msg->src.yrgb_addr + (y_off * stride) + (x_off * pixel_width); -+ *bRGA_SRC_CB_MST = msg->src.uv_addr + uv_y_off * uv_stride + uv_x_off; -+ *bRGA_SRC_CR_MST = msg->src.v_addr + uv_y_off * uv_stride + uv_x_off; -+ -+ if((msg->alpha_rop_flag >> 1) & 1) -+ *bRGA_SRC_CB_MST = (u32)msg->rop_mask_addr; -+ -+ if (msg->render_mode == color_palette_mode) -+ { -+ u8 shift; -+ u16 sw, byte_num; -+ shift = 3 - (msg->palette_mode & 3); -+ sw = msg->src.vir_w; -+ -+ byte_num = sw >> shift; -+ stride = (byte_num + 3) & (~3); -+ } -+ -+ /* src act window / vir window set */ -+ *bRGA_SRC_VIR_INFO = ((stride >> 2) | (msg->src.vir_h)<<16); -+ *bRGA_SRC_ACT_INFO = ((msg->src.act_w-1) | (msg->src.act_h-1)<<16); -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_dst -+Description: -+ fill dst relate reg info -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ ++ ++#include "rga_reg_info.h" ++#include "rga_rop.h" ++#include "rga.h" ++ ++ ++/************************************************************* ++Func: ++ RGA_pixel_width_init ++Description: ++ select pixel_width form data format ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++unsigned char ++RGA_pixel_width_init(unsigned int format) ++{ ++ unsigned char pixel_width; ++ ++ pixel_width = 0; ++ ++ switch(format) ++ { ++ /* RGB FORMAT */ ++ case RK_FORMAT_RGBA_8888 : pixel_width = 4; break; ++ case RK_FORMAT_RGBX_8888 : pixel_width = 4; break; ++ case RK_FORMAT_RGB_888 : pixel_width = 3; break; ++ case RK_FORMAT_BGRA_8888 : pixel_width = 4; break; ++ case RK_FORMAT_RGB_565 : pixel_width = 2; break; ++ case RK_FORMAT_RGBA_5551 : pixel_width = 2; break; ++ case RK_FORMAT_RGBA_4444 : pixel_width = 2; break; ++ case RK_FORMAT_BGR_888 : pixel_width = 3; break; ++ ++ /* YUV FORMAT */ ++ case RK_FORMAT_YCbCr_422_SP : pixel_width = 1; break; ++ case RK_FORMAT_YCbCr_422_P : pixel_width = 1; break; ++ case RK_FORMAT_YCbCr_420_SP : pixel_width = 1; break; ++ case RK_FORMAT_YCbCr_420_P : pixel_width = 1; break; ++ case RK_FORMAT_YCrCb_422_SP : pixel_width = 1; break; ++ case RK_FORMAT_YCrCb_422_P : pixel_width = 1; break; ++ case RK_FORMAT_YCrCb_420_SP : pixel_width = 1; break; ++ case RK_FORMAT_YCrCb_420_P : pixel_width = 1; break; ++ //case default : pixel_width = 0; break; ++ } ++ ++ return pixel_width; ++} ++ ++/************************************************************* ++Func: ++ dst_ctrl_cal ++Description: ++ calculate dst act window position / width / height ++ and set the tile struct ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++static void ++dst_ctrl_cal(const struct rga_req *msg, TILE_INFO *tile) ++{ ++ u32 width = msg->dst.act_w; ++ u32 height = msg->dst.act_h; ++ s32 xoff = msg->dst.x_offset; ++ s32 yoff = msg->dst.y_offset; ++ ++ s32 x0, y0, x1, y1, x2, y2; ++ s32 x00,y00,x10,y10,x20,y20; ++ s32 xx, xy, yx, yy; ++ s32 pos[8]; ++ ++ s32 xmax, xmin, ymax, ymin; ++ ++ s32 sina = msg->sina; /* 16.16 */ ++ s32 cosa = msg->cosa; /* 16.16 */ ++ ++ xmax = xmin = ymax = ymin = 0; ++ ++ if((msg->rotate_mode == 0)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) ++ { ++ pos[0] = xoff; ++ pos[1] = yoff; ++ ++ pos[2] = xoff; ++ pos[3] = yoff + height - 1; ++ ++ pos[4] = xoff + width - 1; ++ pos[5] = yoff + height - 1; ++ ++ pos[6] = xoff + width - 1; ++ pos[7] = yoff; ++ ++ xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); ++ xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); ++ ++ ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); ++ ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); ++ ++ //printk("xmax = %d, xmin = %d, ymin = %d, ymax = %d\n", xmax, xmin, ymin, ymax); ++ } ++ else if(msg->rotate_mode == 1) ++ { ++ if((sina == 0) || (cosa == 0)) ++ { ++ if((sina == 0) && (cosa == -65536)) ++ { ++ /* 180 */ ++ pos[0] = xoff - width + 1; ++ pos[1] = yoff - height + 1; ++ ++ pos[2] = xoff - width + 1; ++ pos[3] = yoff; ++ ++ pos[4] = xoff; ++ pos[5] = yoff; ++ ++ pos[6] = xoff; ++ pos[7] = yoff - height + 1; ++ } ++ else if((cosa == 0)&&(sina == 65536)) ++ { ++ /* 90 */ ++ pos[0] = xoff - height + 1; ++ pos[1] = yoff; ++ ++ pos[2] = xoff - height + 1; ++ pos[3] = yoff + width - 1; ++ ++ pos[4] = xoff; ++ pos[5] = yoff + width - 1; ++ ++ pos[6] = xoff; ++ pos[7] = yoff; ++ } ++ else if((cosa == 0)&&(sina == -65536)) ++ { ++ /* 270 */ ++ pos[0] = xoff; ++ pos[1] = yoff - width + 1; ++ ++ pos[2] = xoff; ++ pos[3] = yoff; ++ ++ pos[4] = xoff + height - 1; ++ pos[5] = yoff; ++ ++ pos[6] = xoff + height - 1; ++ pos[7] = yoff - width + 1; ++ } ++ else ++ { ++ /* 0 */ ++ pos[0] = xoff; ++ pos[1] = yoff; ++ ++ pos[2] = xoff; ++ pos[3] = yoff + height - 1; ++ ++ pos[4] = xoff + width - 1; ++ pos[5] = yoff + height - 1; ++ ++ pos[6] = xoff + width - 1; ++ pos[7] = yoff; ++ } ++ ++ xmax = MIN(MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmax); ++ xmin = MAX(MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6]), msg->clip.xmin); ++ ++ ymax = MIN(MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymax); ++ ymin = MAX(MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7]), msg->clip.ymin); ++ } ++ else ++ { ++ xx = msg->cosa; ++ xy = msg->sina; ++ yx = xy; ++ yy = xx; ++ ++ x0 = width + xoff; ++ y0 = yoff; ++ ++ x1 = xoff; ++ y1 = height + yoff; ++ ++ x2 = width + xoff; ++ y2 = height + yoff; ++ ++ pos[0] = xoff; ++ pos[1] = yoff; ++ ++ pos[2] = x00 = (((x0 - xoff)*xx - (y0 - yoff)*xy)>>16) + xoff; ++ pos[3] = y00 = (((x0 - xoff)*yx + (y0 - yoff)*yy)>>16) + yoff; ++ ++ pos[4] = x10 = (((x1 - xoff)*xx - (y1 - yoff)*xy)>>16) + xoff; ++ pos[5] = y10 = (((x1 - xoff)*yx + (y1 - yoff)*yy)>>16) + yoff; ++ ++ pos[6] = x20 = (((x2 - xoff)*xx - (y2 - yoff)*xy)>>16) + xoff; ++ pos[7] = y20 = (((x2 - xoff)*yx + (y2 - yoff)*yy)>>16) + yoff; ++ ++ xmax = MAX(MAX(MAX(x00, xoff), x10), x20) + 2; ++ xmin = MIN(MIN(MIN(x00, xoff), x10), x20) - 1; ++ ++ ymax = MAX(MAX(MAX(y00, yoff), y10), y20) + 2; ++ ymin = MIN(MIN(MIN(y00, yoff), y10), y20) - 1; ++ ++ xmax = MIN(xmax, msg->clip.xmax); ++ xmin = MAX(xmin, msg->clip.xmin); ++ ++ ymax = MIN(ymax, msg->clip.ymax); ++ ymin = MAX(ymin, msg->clip.ymin); ++ ++ //printk("xmin = %d, xmax = %d, ymin = %d, ymax = %d\n", xmin, xmax, ymin, ymax); ++ } ++ } ++ ++ if ((xmax < xmin) || (ymax < ymin)) { ++ xmin = xmax; ++ ymin = ymax; ++ } ++ ++ if ((xmin >= msg->dst.vir_w)||(xmax < 0)||(ymin >= msg->dst.vir_h)||(ymax < 0)) { ++ xmin = xmax = ymin = ymax = 0; ++ } ++ ++ //printk("xmin = %d, xmax = %d, ymin = %d, ymax = %d\n", xmin, xmax, ymin, ymax); ++ ++ tile->dst_ctrl.w = (xmax - xmin); ++ tile->dst_ctrl.h = (ymax - ymin); ++ tile->dst_ctrl.x_off = xmin; ++ tile->dst_ctrl.y_off = ymin; ++ ++ //printk("tile->dst_ctrl.w = %x, tile->dst_ctrl.h = %x\n", tile->dst_ctrl.w, tile->dst_ctrl.h); ++ ++ tile->tile_x_num = (xmax - xmin + 1 + 7)>>3; ++ tile->tile_y_num = (ymax - ymin + 1 + 7)>>3; ++ ++ tile->dst_x_tmp = xmin - msg->dst.x_offset; ++ tile->dst_y_tmp = ymin - msg->dst.y_offset; ++} ++ ++/************************************************************* ++Func: ++ src_tile_info_cal ++Description: ++ calculate src remap window position / width / height ++ and set the tile struct ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++src_tile_info_cal(const struct rga_req *msg, TILE_INFO *tile) ++{ ++ s32 x0, x1, x2, x3, y0, y1, y2, y3; ++ ++ int64_t xx, xy, yx, yy; ++ ++ int64_t pos[8]; ++ int64_t epos[8]; ++ ++ int64_t x_dx, x_dy, y_dx, y_dy; ++ int64_t x_temp_start, y_temp_start; ++ int64_t xmax, xmin, ymax, ymin; ++ ++ int64_t t_xoff, t_yoff; ++ ++ xx = tile->matrix[0]; /* 32.32 */ ++ xy = tile->matrix[1]; /* 32.32 */ ++ yx = tile->matrix[2]; /* 32.32 */ ++ yy = tile->matrix[3]; /* 32.32 */ ++ ++ if(msg->rotate_mode == 1) ++ { ++ x0 = tile->dst_x_tmp; ++ y0 = tile->dst_y_tmp; ++ ++ x1 = x0; ++ y1 = y0 + 8; ++ ++ x2 = x0 + 8; ++ y2 = y0 + 8; ++ ++ x3 = x0 + 8; ++ y3 = y0; ++ ++ pos[0] = (x0*xx + y0*yx); ++ pos[1] = (x0*xy + y0*yy); ++ ++ pos[2] = (x1*xx + y1*yx); ++ pos[3] = (x1*xy + y1*yy); ++ ++ pos[4] = (x2*xx + y2*yx); ++ pos[5] = (x2*xy + y2*yy); ++ ++ pos[6] = (x3*xx + y3*yx); ++ pos[7] = (x3*xy + y3*yy); ++ ++ y1 = y0 + 7; ++ x2 = x0 + 7; ++ y2 = y0 + 7; ++ x3 = x0 + 7; ++ ++ epos[0] = pos[0]; ++ epos[1] = pos[1]; ++ ++ epos[2] = (x1*xx + y1*yx); ++ epos[3] = (x1*xy + y1*yy); ++ ++ epos[4] = (x2*xx + y2*yx); ++ epos[5] = (x2*xy + y2*yy); ++ ++ epos[6] = (x3*xx + y3*yx); ++ epos[7] = (x3*xy + y3*yy); ++ ++ x_dx = pos[6] - pos[0]; ++ x_dy = pos[7] - pos[1]; ++ ++ y_dx = pos[2] - pos[0]; ++ y_dy = pos[3] - pos[1]; ++ ++ tile->x_dx = (s32)(x_dx >> 22 ); ++ tile->x_dy = (s32)(x_dy >> 22 ); ++ tile->y_dx = (s32)(y_dx >> 22 ); ++ tile->y_dy = (s32)(y_dy >> 22 ); ++ ++ x_temp_start = x0*xx + y0*yx; ++ y_temp_start = x0*xy + y0*yy; ++ ++ xmax = (MAX(MAX(MAX(epos[0], epos[2]), epos[4]), epos[6])); ++ xmin = (MIN(MIN(MIN(epos[0], epos[2]), epos[4]), epos[6])); ++ ++ ymax = (MAX(MAX(MAX(epos[1], epos[3]), epos[5]), epos[7])); ++ ymin = (MIN(MIN(MIN(epos[1], epos[3]), epos[5]), epos[7])); ++ ++ t_xoff = (x_temp_start - xmin)>>18; ++ t_yoff = (y_temp_start - ymin)>>18; ++ ++ tile->tile_xoff = (s32)t_xoff; ++ tile->tile_yoff = (s32)t_yoff; ++ ++ tile->tile_w = (u16)((xmax - xmin)>>21); //.11 ++ tile->tile_h = (u16)((ymax - ymin)>>21); //.11 ++ ++ tile->tile_start_x_coor = (s16)(xmin>>29); //.3 ++ tile->tile_start_y_coor = (s16)(ymin>>29); //.3 ++ } ++ else if (msg->rotate_mode == 2) ++ { ++ tile->x_dx = (s32)((8*xx)>>22); ++ tile->x_dy = 0; ++ tile->y_dx = 0; ++ tile->y_dy = (s32)((8*yy)>>22); ++ ++ tile->tile_w = ABS((s32)((7*xx)>>21)); ++ tile->tile_h = ABS((s32)((7*yy)>>21)); ++ ++ tile->tile_xoff = ABS((s32)((7*xx)>>18)); ++ tile->tile_yoff = 0; ++ ++ tile->tile_start_x_coor = (((msg->src.act_w - 1)<<11) - (tile->tile_w))>>8; ++ tile->tile_start_y_coor = 0; ++ } ++ else if (msg->rotate_mode == 3) ++ { ++ tile->x_dx = (s32)((8*xx)>>22); ++ tile->x_dy = 0; ++ tile->y_dx = 0; ++ tile->y_dy = (s32)((8*yy)>>22); ++ ++ tile->tile_w = ABS((s32)((7*xx)>>21)); ++ tile->tile_h = ABS((s32)((7*yy)>>21)); ++ ++ tile->tile_xoff = 0; ++ tile->tile_yoff = ABS((s32)((7*yy)>>18)); ++ ++ tile->tile_start_x_coor = 0; ++ tile->tile_start_y_coor = (((msg->src.act_h - 1)<<11) - (tile->tile_h))>>8; ++ } ++ ++ if ((msg->scale_mode == 2)||(msg->alpha_rop_flag >> 7)) ++ { ++ tile->tile_start_x_coor -= (1<<3); ++ tile->tile_start_y_coor -= (1<<3); ++ tile->tile_w += (2 << 11); ++ tile->tile_h += (2 << 11); ++ tile->tile_xoff += (1<<14); ++ tile->tile_yoff += (1<<14); ++ } ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_mode_ctrl ++Description: ++ fill mode ctrl reg info ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++RGA_set_mode_ctrl(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_MODE_CTL; ++ u32 reg = 0; ++ ++ u8 src_rgb_pack = 0; ++ u8 src_format = 0; ++ u8 src_rb_swp = 0; ++ u8 src_a_swp = 0; ++ u8 src_cbcr_swp = 0; ++ ++ u8 dst_rgb_pack = 0; ++ u8 dst_format = 0; ++ u8 dst_rb_swp = 0; ++ u8 dst_a_swp = 0; ++ ++ bRGA_MODE_CTL = (u32 *)(base + RGA_MODE_CTRL_OFFSET); ++ ++ reg = ((reg & (~m_RGA_MODE_CTRL_2D_RENDER_MODE)) | (s_RGA_MODE_CTRL_2D_RENDER_MODE(msg->render_mode))); ++ ++ /* src info set */ ++ ++ if (msg->render_mode == color_palette_mode || msg->render_mode == update_palette_table_mode) ++ { ++ src_format = 0x10 | (msg->palette_mode & 3); ++ } ++ else ++ { ++ switch (msg->src.format) ++ { ++ case RK_FORMAT_RGBA_8888 : src_format = 0x0; break; ++ case RK_FORMAT_RGBA_4444 : src_format = 0x3; break; ++ case RK_FORMAT_RGBA_5551 : src_format = 0x2; break; ++ case RK_FORMAT_BGRA_8888 : src_format = 0x0; src_rb_swp = 0x1; break; ++ case RK_FORMAT_RGBX_8888 : src_format = 0x0; break; ++ case RK_FORMAT_RGB_565 : src_format = 0x1; break; ++ case RK_FORMAT_RGB_888 : src_format = 0x0; src_rgb_pack = 1; break; ++ case RK_FORMAT_BGR_888 : src_format = 0x0; src_rgb_pack = 1; src_rb_swp = 1; break; ++ ++ case RK_FORMAT_YCbCr_422_SP : src_format = 0x4; break; ++ case RK_FORMAT_YCbCr_422_P : src_format = 0x5; break; ++ case RK_FORMAT_YCbCr_420_SP : src_format = 0x6; break; ++ case RK_FORMAT_YCbCr_420_P : src_format = 0x7; break; ++ ++ case RK_FORMAT_YCrCb_422_SP : src_format = 0x4; src_cbcr_swp = 1; break; ++ case RK_FORMAT_YCrCb_422_P : src_format = 0x5; src_cbcr_swp = 1; break; ++ case RK_FORMAT_YCrCb_420_SP : src_format = 0x6; src_cbcr_swp = 1; break; ++ case RK_FORMAT_YCrCb_420_P : src_format = 0x7; src_cbcr_swp = 1; break; ++ } ++ } ++ ++ src_a_swp = msg->src.alpha_swap & 1; ++ ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RGB_PACK)) | (s_RGA_MODE_CTRL_SRC_RGB_PACK(src_rgb_pack))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_FORMAT)) | (s_RGA_MODE_CTRL_SRC_FORMAT(src_format))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_RB_SWAP)) | (s_RGA_MODE_CTRL_SRC_RB_SWAP(src_rb_swp))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(src_a_swp))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE )) | (s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE (src_cbcr_swp))); ++ ++ ++ /* YUV2RGB MODE */ ++ reg = ((reg & (~m_RGA_MODE_CTRL_YUV2RGB_CON_MODE)) | (s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(msg->yuv2rgb_mode))); ++ ++ /* ROTATE MODE */ ++ reg = ((reg & (~m_RGA_MODE_CTRL_ROTATE_MODE)) | (s_RGA_MODE_CTRL_ROTATE_MODE(msg->rotate_mode))); ++ ++ /* SCALE MODE */ ++ reg = ((reg & (~m_RGA_MODE_CTRL_SCALE_MODE)) | (s_RGA_MODE_CTRL_SCALE_MODE(msg->scale_mode))); ++ ++ /* COLOR FILL MODE */ ++ reg = ((reg & (~m_RGA_MODE_CTRL_PAT_SEL)) | (s_RGA_MODE_CTRL_PAT_SEL(msg->color_fill_mode))); ++ ++ ++ if ((msg->render_mode == update_palette_table_mode)||(msg->render_mode == update_patten_buff_mode)) ++ { ++ dst_format = msg->pat.format; ++ } ++ else ++ { ++ dst_format = (u8)msg->dst.format; ++ } ++ ++ /* dst info set */ ++ switch (dst_format) ++ { ++ case RK_FORMAT_BGRA_8888 : dst_format = 0x0; dst_rb_swp = 0x1; break; ++ case RK_FORMAT_RGBA_4444 : dst_format = 0x3; break; ++ case RK_FORMAT_RGBA_5551 : dst_format = 0x2; break; ++ case RK_FORMAT_RGBA_8888 : dst_format = 0x0; break; ++ case RK_FORMAT_RGB_565 : dst_format = 0x1; break; ++ case RK_FORMAT_RGB_888 : dst_format = 0x0; dst_rgb_pack = 0x1; break; ++ case RK_FORMAT_BGR_888 : dst_format = 0x0; dst_rgb_pack = 0x1; dst_rb_swp = 1; break; ++ case RK_FORMAT_RGBX_8888 : dst_format = 0x0; break; ++ } ++ ++ dst_a_swp = msg->dst.alpha_swap & 1; ++ ++ reg = ((reg & (~m_RGA_MODE_CTRL_DST_FORMAT)) | (s_RGA_MODE_CTRL_DST_FORMAT(dst_format))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_DST_RGB_PACK)) | (s_RGA_MODE_CTRL_DST_RGB_PACK(dst_rgb_pack))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_DST_RB_SWAP)) | (s_RGA_MODE_CTRL_DST_RB_SWAP(dst_rb_swp))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_SWAP)) | (s_RGA_MODE_CTRL_DST_ALPHA_SWAP(dst_a_swp))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_LUT_ENDIAN_MODE)) | (s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(msg->endian_mode & 1))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_SRC_TRANS_MODE)) | (s_RGA_MODE_CTRL_SRC_TRANS_MODE(msg->src_trans_mode))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_ZERO_MODE_ENABLE)) | (s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(msg->alpha_rop_mode >> 4))); ++ reg = ((reg & (~m_RGA_MODE_CTRL_DST_ALPHA_ENABLE)) | (s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(msg->alpha_rop_mode >> 5))); ++ ++ *bRGA_MODE_CTL = reg; ++ ++} ++ ++ ++ ++/************************************************************* ++Func: ++ RGA_set_src ++Description: ++ fill src relate reg info ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++RGA_set_src(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_SRC_VIR_INFO; ++ u32 *bRGA_SRC_ACT_INFO; ++ u32 *bRGA_SRC_Y_MST; ++ u32 *bRGA_SRC_CB_MST; ++ u32 *bRGA_SRC_CR_MST; ++ ++ s16 x_off, y_off, stride; ++ s16 uv_x_off, uv_y_off, uv_stride; ++ u32 pixel_width; ++ ++ uv_x_off = uv_y_off = uv_stride = 0; ++ ++ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); ++ bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); ++ bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); ++ bRGA_SRC_VIR_INFO = (u32 *)(base + RGA_SRC_VIR_INFO_OFFSET); ++ bRGA_SRC_ACT_INFO = (u32 *)(base + RGA_SRC_ACT_INFO_OFFSET); ++ ++ x_off = msg->src.x_offset; ++ y_off = msg->src.y_offset; ++ ++ pixel_width = RGA_pixel_width_init(msg->src.format); ++ ++ stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); ++ ++ switch(msg->src.format) ++ { ++ case RK_FORMAT_YCbCr_422_SP : ++ uv_stride = stride; ++ uv_x_off = x_off; ++ uv_y_off = y_off; ++ break; ++ case RK_FORMAT_YCbCr_422_P : ++ uv_stride = stride >> 1; ++ uv_x_off = x_off >> 1; ++ uv_y_off = y_off; ++ break; ++ case RK_FORMAT_YCbCr_420_SP : ++ uv_stride = stride; ++ uv_x_off = x_off; ++ uv_y_off = y_off >> 1; ++ break; ++ case RK_FORMAT_YCbCr_420_P : ++ uv_stride = stride >> 1; ++ uv_x_off = x_off >> 1; ++ uv_y_off = y_off >> 1; ++ break; ++ case RK_FORMAT_YCrCb_422_SP : ++ uv_stride = stride; ++ uv_x_off = x_off; ++ uv_y_off = y_off; ++ break; ++ case RK_FORMAT_YCrCb_422_P : ++ uv_stride = stride >> 1; ++ uv_x_off = x_off >> 1; ++ uv_y_off = y_off; ++ break; ++ case RK_FORMAT_YCrCb_420_SP : ++ uv_stride = stride; ++ uv_x_off = x_off; ++ uv_y_off = y_off >> 1; ++ break; ++ case RK_FORMAT_YCrCb_420_P : ++ uv_stride = stride >> 1; ++ uv_x_off = x_off >> 1; ++ uv_y_off = y_off >> 1; ++ break; ++ } ++ ++ ++ /* src addr set */ ++ *bRGA_SRC_Y_MST = msg->src.yrgb_addr + (y_off * stride) + (x_off * pixel_width); ++ *bRGA_SRC_CB_MST = msg->src.uv_addr + uv_y_off * uv_stride + uv_x_off; ++ *bRGA_SRC_CR_MST = msg->src.v_addr + uv_y_off * uv_stride + uv_x_off; ++ ++ if((msg->alpha_rop_flag >> 1) & 1) ++ *bRGA_SRC_CB_MST = (u32)msg->rop_mask_addr; ++ ++ if (msg->render_mode == color_palette_mode) ++ { ++ u8 shift; ++ u16 sw, byte_num; ++ shift = 3 - (msg->palette_mode & 3); ++ sw = msg->src.vir_w; ++ ++ byte_num = sw >> shift; ++ stride = (byte_num + 3) & (~3); ++ } ++ ++ /* src act window / vir window set */ ++ *bRGA_SRC_VIR_INFO = ((stride >> 2) | (msg->src.vir_h)<<16); ++ *bRGA_SRC_ACT_INFO = ((msg->src.act_w-1) | (msg->src.act_h-1)<<16); ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_dst ++Description: ++ fill dst relate reg info ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ + +static s32 RGA_set_dst(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_DST_MST; -+ u32 *bRGA_DST_UV_MST; -+ u32 *bRGA_DST_VIR_INFO; -+ u32 *bRGA_DST_CTR_INFO; -+ u32 *bRGA_PRESCL_CB_MST; -+ u32 *bRGA_PRESCL_CR_MST; -+ u32 *bRGA_YUV_OUT_CFG; -+ -+ u32 reg = 0; -+ -+ u8 pw; -+ s16 x_off = msg->dst.x_offset; -+ s16 y_off = msg->dst.y_offset; -+ u16 stride, rop_mask_stride; -+ -+ bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); -+ bRGA_DST_UV_MST = (u32 *)(base + RGA_DST_UV_MST_OFFSET); -+ bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); -+ bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); -+ bRGA_PRESCL_CB_MST = (u32 *)(base + RGA_PRESCL_CB_MST_OFFSET); -+ bRGA_PRESCL_CR_MST = (u32 *)(base + RGA_PRESCL_CR_MST_OFFSET); -+ bRGA_YUV_OUT_CFG = (u32 *)(base + RGA_YUV_OUT_CFG_OFFSET); -+ -+ pw = RGA_pixel_width_init(msg->dst.format); -+ -+ stride = (msg->dst.vir_w * pw + 3) & (~3); -+ -+ *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (y_off * stride) + (x_off * pw); -+ ++{ ++ u32 *bRGA_DST_MST; ++ u32 *bRGA_DST_UV_MST; ++ u32 *bRGA_DST_VIR_INFO; ++ u32 *bRGA_DST_CTR_INFO; ++ u32 *bRGA_PRESCL_CB_MST; ++ u32 *bRGA_PRESCL_CR_MST; ++ u32 *bRGA_YUV_OUT_CFG; ++ ++ u32 reg = 0; ++ ++ u8 pw; ++ s16 x_off = msg->dst.x_offset; ++ s16 y_off = msg->dst.y_offset; ++ u16 stride, rop_mask_stride; ++ ++ bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); ++ bRGA_DST_UV_MST = (u32 *)(base + RGA_DST_UV_MST_OFFSET); ++ bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); ++ bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); ++ bRGA_PRESCL_CB_MST = (u32 *)(base + RGA_PRESCL_CB_MST_OFFSET); ++ bRGA_PRESCL_CR_MST = (u32 *)(base + RGA_PRESCL_CR_MST_OFFSET); ++ bRGA_YUV_OUT_CFG = (u32 *)(base + RGA_YUV_OUT_CFG_OFFSET); ++ ++ pw = RGA_pixel_width_init(msg->dst.format); ++ ++ stride = (msg->dst.vir_w * pw + 3) & (~3); ++ ++ *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (y_off * stride) + (x_off * pw); ++ + *bRGA_DST_UV_MST = 0; + *bRGA_YUV_OUT_CFG = 0; + if (msg->rotate_mode == 1) { @@ -1844454,872 +1844454,872 @@ index 000000000..94a6305b8 + } + } + -+ switch(msg->dst.format) -+ { -+ case RK_FORMAT_YCbCr_422_SP : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); ++ switch(msg->dst.format) ++ { ++ case RK_FORMAT_YCbCr_422_SP : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); + *bRGA_DST_UV_MST = (u32)msg->dst.uv_addr + (y_off * stride) + x_off; + *bRGA_YUV_OUT_CFG |= (((msg->yuv2rgb_mode >> 2) & 3) << 4) | (0 << 3) | (0 << 1) | 1; -+ break; -+ case RK_FORMAT_YCbCr_422_P : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); -+ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); -+ break; -+ case RK_FORMAT_YCbCr_420_SP : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); ++ break; ++ case RK_FORMAT_YCbCr_422_P : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); ++ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); ++ break; ++ case RK_FORMAT_YCbCr_420_SP : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); + *bRGA_DST_UV_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + x_off; + *bRGA_YUV_OUT_CFG |= (((msg->yuv2rgb_mode >> 2) & 3) << 4) | (0 << 3) | (1 << 1) | 1; -+ break; -+ case RK_FORMAT_YCbCr_420_P : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); -+ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); -+ break; -+ case RK_FORMAT_YCrCb_422_SP : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); ++ break; ++ case RK_FORMAT_YCbCr_420_P : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); ++ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); ++ break; ++ case RK_FORMAT_YCrCb_422_SP : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off) * pw); + *bRGA_DST_UV_MST = (u32)msg->dst.uv_addr + (y_off * stride) + x_off; + *bRGA_YUV_OUT_CFG |= (((msg->yuv2rgb_mode >> 2) & 3) << 4) | (1 << 3) | (0 << 1) | 1; -+ break; -+ case RK_FORMAT_YCrCb_422_P : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); -+ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); -+ break; -+ case RK_FORMAT_YCrCb_420_SP : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); ++ break; ++ case RK_FORMAT_YCrCb_422_P : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off) * stride) + ((x_off>>1) * pw); ++ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off) * stride) + ((x_off>>1) * pw); ++ break; ++ case RK_FORMAT_YCrCb_420_SP : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off) * pw); + *bRGA_DST_UV_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + x_off; + *bRGA_YUV_OUT_CFG |= (((msg->yuv2rgb_mode >> 2) & 3) << 4) | (1 << 3) | (1 << 1) | 1; -+ break; -+ case RK_FORMAT_YCrCb_420_P : -+ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); -+ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); -+ break; -+ } -+ -+ rop_mask_stride = (((msg->src.vir_w + 7)>>3) + 3) & (~3);//not dst_vir.w,hxx,2011.7.21 -+ -+ reg = (stride >> 2) & 0xffff; -+ reg = reg | ((rop_mask_stride>>2) << 16); -+ -+ #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3188) -+ //reg = reg | ((msg->alpha_rop_mode & 3) << 28); -+ reg = reg | (1 << 28); -+ #endif -+ -+ if (msg->render_mode == line_point_drawing_mode) -+ { -+ reg &= 0xffff; -+ reg = reg | (msg->dst.vir_h << 16); -+ } -+ -+ *bRGA_DST_VIR_INFO = reg; -+ *bRGA_DST_CTR_INFO = (msg->dst.act_w - 1) | ((msg->dst.act_h - 1) << 16); ++ break; ++ case RK_FORMAT_YCrCb_420_P : ++ *bRGA_PRESCL_CB_MST = (u32)msg->dst.uv_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); ++ *bRGA_PRESCL_CR_MST = (u32)msg->dst.v_addr + ((y_off>>1) * stride) + ((x_off>>1) * pw); ++ break; ++ } ++ ++ rop_mask_stride = (((msg->src.vir_w + 7)>>3) + 3) & (~3);//not dst_vir.w,hxx,2011.7.21 ++ ++ reg = (stride >> 2) & 0xffff; ++ reg = reg | ((rop_mask_stride>>2) << 16); ++ ++ #if defined(CONFIG_ARCH_RK2928) || defined(CONFIG_ARCH_RK3188) ++ //reg = reg | ((msg->alpha_rop_mode & 3) << 28); ++ reg = reg | (1 << 28); ++ #endif ++ ++ if (msg->render_mode == line_point_drawing_mode) ++ { ++ reg &= 0xffff; ++ reg = reg | (msg->dst.vir_h << 16); ++ } ++ ++ *bRGA_DST_VIR_INFO = reg; ++ *bRGA_DST_CTR_INFO = (msg->dst.act_w - 1) | ((msg->dst.act_h - 1) << 16); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0)) -+ if (msg->render_mode == pre_scaling_mode) { -+ *bRGA_YUV_OUT_CFG &= 0xfffffffe; -+ } -+#endif -+ return 0; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_alpha_rop -+Description: -+ fill alpha rop some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+static void -+RGA_set_alpha_rop(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_ALPHA_CON; -+ u32 *bRGA_ROP_CON0; -+ u32 *bRGA_ROP_CON1; -+ u32 reg = 0; -+ u32 rop_con0, rop_con1; -+ -+ u8 rop_mode = (msg->alpha_rop_mode) & 3; -+ u8 alpha_mode = msg->alpha_rop_mode & 3; -+ -+ rop_con0 = rop_con1 = 0; -+ -+ bRGA_ALPHA_CON = (u32 *)(base + RGA_ALPHA_CON_OFFSET); -+ -+ reg = ((reg & (~m_RGA_ALPHA_CON_ENABLE) )| (s_RGA_ALPHA_CON_ENABLE(msg->alpha_rop_flag & 1))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_A_OR_R_SEL)) | (s_RGA_ALPHA_CON_A_OR_R_SEL((msg->alpha_rop_flag >> 1) & 1))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_ALPHA_MODE)) | (s_RGA_ALPHA_CON_ALPHA_MODE(alpha_mode))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_PD_MODE)) | (s_RGA_ALPHA_CON_PD_MODE(msg->PD_mode))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_SET_CONSTANT_VALUE)) | (s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(msg->alpha_global_value))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_PD_M_SEL)) | (s_RGA_ALPHA_CON_PD_M_SEL(msg->alpha_rop_flag >> 3))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_FADING_ENABLE)) | (s_RGA_ALPHA_CON_FADING_ENABLE(msg->alpha_rop_flag >> 2))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_ROP_MODE_SEL)) | (s_RGA_ALPHA_CON_ROP_MODE_SEL(rop_mode))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_CAL_MODE_SEL)) | (s_RGA_ALPHA_CON_CAL_MODE_SEL(msg->alpha_rop_flag >> 4))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_DITHER_ENABLE)) | (s_RGA_ALPHA_CON_DITHER_ENABLE(msg->alpha_rop_flag >> 5))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_GRADIENT_CAL_MODE)) | (s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(msg->alpha_rop_flag >> 6))); -+ reg = ((reg & (~m_RGA_ALPHA_CON_AA_SEL)) | (s_RGA_ALPHA_CON_AA_SEL(msg->alpha_rop_flag >> 7))); -+ -+ *bRGA_ALPHA_CON = reg; -+ -+ if(rop_mode == 0) { -+ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; -+ } -+ else if(rop_mode == 1) { -+ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; -+ } -+ else if(rop_mode == 2) { -+ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; -+ rop_con1 = ROP3_code[(msg->rop_code & 0xff00)>>8]; -+ } -+ -+ bRGA_ROP_CON0 = (u32 *)(base + RGA_ROP_CON0_OFFSET); -+ bRGA_ROP_CON1 = (u32 *)(base + RGA_ROP_CON1_OFFSET); -+ -+ *bRGA_ROP_CON0 = (u32)rop_con0; -+ *bRGA_ROP_CON1 = (u32)rop_con1; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_color -+Description: -+ fill color some relate reg bit -+ bg_color/fg_color -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+RGA_set_color(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_SRC_TR_COLOR0; -+ u32 *bRGA_SRC_TR_COLOR1; -+ u32 *bRGA_SRC_BG_COLOR; -+ u32 *bRGA_SRC_FG_COLOR; -+ -+ -+ bRGA_SRC_BG_COLOR = (u32 *)(base + RGA_SRC_BG_COLOR_OFFSET); -+ bRGA_SRC_FG_COLOR = (u32 *)(base + RGA_SRC_FG_COLOR_OFFSET); -+ -+ *bRGA_SRC_BG_COLOR = msg->bg_color; /* 1bpp 0 */ -+ *bRGA_SRC_FG_COLOR = msg->fg_color; /* 1bpp 1 */ -+ -+ bRGA_SRC_TR_COLOR0 = (u32 *)(base + RGA_SRC_TR_COLOR0_OFFSET); -+ bRGA_SRC_TR_COLOR1 = (u32 *)(base + RGA_SRC_TR_COLOR1_OFFSET); -+ -+ *bRGA_SRC_TR_COLOR0 = msg->color_key_min; -+ *bRGA_SRC_TR_COLOR1 = msg->color_key_max; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_fading -+Description: -+ fill fading some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ ++ if (msg->render_mode == pre_scaling_mode) { ++ *bRGA_YUV_OUT_CFG &= 0xfffffffe; ++ } ++#endif ++ return 0; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_alpha_rop ++Description: ++ fill alpha rop some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++static void ++RGA_set_alpha_rop(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_ALPHA_CON; ++ u32 *bRGA_ROP_CON0; ++ u32 *bRGA_ROP_CON1; ++ u32 reg = 0; ++ u32 rop_con0, rop_con1; ++ ++ u8 rop_mode = (msg->alpha_rop_mode) & 3; ++ u8 alpha_mode = msg->alpha_rop_mode & 3; ++ ++ rop_con0 = rop_con1 = 0; ++ ++ bRGA_ALPHA_CON = (u32 *)(base + RGA_ALPHA_CON_OFFSET); ++ ++ reg = ((reg & (~m_RGA_ALPHA_CON_ENABLE) )| (s_RGA_ALPHA_CON_ENABLE(msg->alpha_rop_flag & 1))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_A_OR_R_SEL)) | (s_RGA_ALPHA_CON_A_OR_R_SEL((msg->alpha_rop_flag >> 1) & 1))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_ALPHA_MODE)) | (s_RGA_ALPHA_CON_ALPHA_MODE(alpha_mode))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_PD_MODE)) | (s_RGA_ALPHA_CON_PD_MODE(msg->PD_mode))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_SET_CONSTANT_VALUE)) | (s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(msg->alpha_global_value))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_PD_M_SEL)) | (s_RGA_ALPHA_CON_PD_M_SEL(msg->alpha_rop_flag >> 3))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_FADING_ENABLE)) | (s_RGA_ALPHA_CON_FADING_ENABLE(msg->alpha_rop_flag >> 2))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_ROP_MODE_SEL)) | (s_RGA_ALPHA_CON_ROP_MODE_SEL(rop_mode))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_CAL_MODE_SEL)) | (s_RGA_ALPHA_CON_CAL_MODE_SEL(msg->alpha_rop_flag >> 4))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_DITHER_ENABLE)) | (s_RGA_ALPHA_CON_DITHER_ENABLE(msg->alpha_rop_flag >> 5))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_GRADIENT_CAL_MODE)) | (s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(msg->alpha_rop_flag >> 6))); ++ reg = ((reg & (~m_RGA_ALPHA_CON_AA_SEL)) | (s_RGA_ALPHA_CON_AA_SEL(msg->alpha_rop_flag >> 7))); ++ ++ *bRGA_ALPHA_CON = reg; ++ ++ if(rop_mode == 0) { ++ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; ++ } ++ else if(rop_mode == 1) { ++ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; ++ } ++ else if(rop_mode == 2) { ++ rop_con0 = ROP3_code[(msg->rop_code & 0xff)]; ++ rop_con1 = ROP3_code[(msg->rop_code & 0xff00)>>8]; ++ } ++ ++ bRGA_ROP_CON0 = (u32 *)(base + RGA_ROP_CON0_OFFSET); ++ bRGA_ROP_CON1 = (u32 *)(base + RGA_ROP_CON1_OFFSET); ++ ++ *bRGA_ROP_CON0 = (u32)rop_con0; ++ *bRGA_ROP_CON1 = (u32)rop_con1; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_color ++Description: ++ fill color some relate reg bit ++ bg_color/fg_color ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++RGA_set_color(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_SRC_TR_COLOR0; ++ u32 *bRGA_SRC_TR_COLOR1; ++ u32 *bRGA_SRC_BG_COLOR; ++ u32 *bRGA_SRC_FG_COLOR; ++ ++ ++ bRGA_SRC_BG_COLOR = (u32 *)(base + RGA_SRC_BG_COLOR_OFFSET); ++ bRGA_SRC_FG_COLOR = (u32 *)(base + RGA_SRC_FG_COLOR_OFFSET); ++ ++ *bRGA_SRC_BG_COLOR = msg->bg_color; /* 1bpp 0 */ ++ *bRGA_SRC_FG_COLOR = msg->fg_color; /* 1bpp 1 */ ++ ++ bRGA_SRC_TR_COLOR0 = (u32 *)(base + RGA_SRC_TR_COLOR0_OFFSET); ++ bRGA_SRC_TR_COLOR1 = (u32 *)(base + RGA_SRC_TR_COLOR1_OFFSET); ++ ++ *bRGA_SRC_TR_COLOR0 = msg->color_key_min; ++ *bRGA_SRC_TR_COLOR1 = msg->color_key_max; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_fading ++Description: ++ fill fading some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ + +static s32 -+RGA_set_fading(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_FADING_CON; -+ u8 r, g, b; -+ u32 reg = 0; -+ -+ bRGA_FADING_CON = (u32 *)(base + RGA_FADING_CON_OFFSET); -+ -+ b = msg->fading.b; -+ g = msg->fading.g; -+ r = msg->fading.r; -+ -+ reg = (r<<8) | (g<<16) | (b<<24) | reg; -+ -+ *bRGA_FADING_CON = reg; -+ -+ return 0; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_pat -+Description: -+ fill patten some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ ++RGA_set_fading(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_FADING_CON; ++ u8 r, g, b; ++ u32 reg = 0; ++ ++ bRGA_FADING_CON = (u32 *)(base + RGA_FADING_CON_OFFSET); ++ ++ b = msg->fading.b; ++ g = msg->fading.g; ++ r = msg->fading.r; ++ ++ reg = (r<<8) | (g<<16) | (b<<24) | reg; ++ ++ *bRGA_FADING_CON = reg; ++ ++ return 0; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_pat ++Description: ++ fill patten some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ + +static s32 -+RGA_set_pat(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_PAT_CON; -+ u32 *bRGA_PAT_START_POINT; -+ u32 reg = 0; -+ -+ bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); -+ -+ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); -+ -+ *bRGA_PAT_START_POINT = (msg->pat.act_w * msg->pat.y_offset) + msg->pat.x_offset; -+ -+ reg = (msg->pat.act_w - 1) | ((msg->pat.act_h - 1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); -+ *bRGA_PAT_CON = reg; -+ -+ return 0; -+} -+ -+ -+ -+ -+/************************************************************* -+Func: -+ RGA_set_bitblt_reg_info -+Description: -+ fill bitblt mode relate ren info -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+RGA_set_bitblt_reg_info(u8 *base, const struct rga_req * msg, TILE_INFO *tile) -+{ -+ u32 *bRGA_SRC_Y_MST; -+ u32 *bRGA_SRC_CB_MST; -+ u32 *bRGA_SRC_CR_MST; -+ u32 *bRGA_SRC_X_PARA; -+ u32 *bRGA_SRC_Y_PARA; -+ u32 *bRGA_SRC_TILE_XINFO; -+ u32 *bRGA_SRC_TILE_YINFO; -+ u32 *bRGA_SRC_TILE_H_INCR; -+ u32 *bRGA_SRC_TILE_V_INCR; -+ u32 *bRGA_SRC_TILE_OFFSETX; -+ u32 *bRGA_SRC_TILE_OFFSETY; -+ -+ u32 *bRGA_DST_MST; -+ u32 *bRGA_DST_CTR_INFO; -+ -+ s32 m0, m1, m2, m3; -+ s32 pos[8]; -+ //s32 x_dx, x_dy, y_dx, y_dy; -+ s32 xmin, xmax, ymin, ymax; -+ s32 xp, yp; -+ u32 y_addr, u_addr, v_addr; -+ u32 pixel_width, stride; -+ -+ u_addr = v_addr = 0; -+ -+ /* src info */ -+ -+ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); -+ bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); -+ bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); -+ -+ bRGA_SRC_X_PARA = (u32 *)(base + RGA_SRC_X_PARA_OFFSET); -+ bRGA_SRC_Y_PARA = (u32 *)(base + RGA_SRC_Y_PARA_OFFSET); -+ -+ bRGA_SRC_TILE_XINFO = (u32 *)(base + RGA_SRC_TILE_XINFO_OFFSET); -+ bRGA_SRC_TILE_YINFO = (u32 *)(base + RGA_SRC_TILE_YINFO_OFFSET); -+ bRGA_SRC_TILE_H_INCR = (u32 *)(base + RGA_SRC_TILE_H_INCR_OFFSET); -+ bRGA_SRC_TILE_V_INCR = (u32 *)(base + RGA_SRC_TILE_V_INCR_OFFSET); -+ bRGA_SRC_TILE_OFFSETX = (u32 *)(base + RGA_SRC_TILE_OFFSETX_OFFSET); -+ bRGA_SRC_TILE_OFFSETY = (u32 *)(base + RGA_SRC_TILE_OFFSETY_OFFSET); -+ -+ bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); -+ bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); -+ -+ /* Matrix reg fill */ -+ m0 = (s32)(tile->matrix[0] >> 18); -+ m1 = (s32)(tile->matrix[1] >> 18); -+ m2 = (s32)(tile->matrix[2] >> 18); -+ m3 = (s32)(tile->matrix[3] >> 18); -+ -+ *bRGA_SRC_X_PARA = (m0 & 0xffff) | (m2 << 16); -+ *bRGA_SRC_Y_PARA = (m1 & 0xffff) | (m3 << 16); -+ -+ /* src tile information setting */ -+ if(msg->rotate_mode != 0)//add by hxx,2011.7.12,for rtl0707,when line scanning ,do not calc src tile info -+ { -+ *bRGA_SRC_TILE_XINFO = (tile->tile_start_x_coor & 0xffff) | (tile->tile_w << 16); -+ *bRGA_SRC_TILE_YINFO = (tile->tile_start_y_coor & 0xffff) | (tile->tile_h << 16); -+ -+ *bRGA_SRC_TILE_H_INCR = ((tile->x_dx) & 0xffff) | ((tile->x_dy) << 16); -+ *bRGA_SRC_TILE_V_INCR = ((tile->y_dx) & 0xffff) | ((tile->y_dy) << 16); -+ -+ *bRGA_SRC_TILE_OFFSETX = tile->tile_xoff; -+ *bRGA_SRC_TILE_OFFSETY = tile->tile_yoff; -+ } -+ -+ pixel_width = RGA_pixel_width_init(msg->src.format); -+ -+ stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); -+ -+ if ((msg->rotate_mode == 1)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) -+ { -+ pos[0] = tile->tile_start_x_coor<<8; -+ pos[1] = tile->tile_start_y_coor<<8; -+ -+ pos[2] = pos[0]; -+ pos[3] = pos[1] + tile->tile_h; -+ -+ pos[4] = pos[0] + tile->tile_w; -+ pos[5] = pos[1] + tile->tile_h; -+ -+ pos[6] = pos[0] + tile->tile_w; -+ pos[7] = pos[1]; -+ -+ pos[0] >>= 11; -+ pos[1] >>= 11; -+ -+ pos[2] >>= 11; -+ pos[3] >>= 11; -+ -+ pos[4] >>= 11; -+ pos[5] >>= 11; -+ -+ pos[6] >>= 11; -+ pos[7] >>= 11; -+ -+ xmax = (MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]) + 1); -+ xmin = (MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6])); -+ -+ ymax = (MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]) + 1); -+ ymin = (MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7])); -+ -+ xp = xmin + msg->src.x_offset; -+ yp = ymin + msg->src.y_offset; -+ -+ if (!((xmax < 0)||(xmin > msg->src.act_w - 1)||(ymax < 0)||(ymin > msg->src.act_h - 1))) -+ { -+ xp = CLIP(xp, msg->src.x_offset, msg->src.x_offset + msg->src.act_w - 1); -+ yp = CLIP(yp, msg->src.y_offset, msg->src.y_offset + msg->src.act_h - 1); -+ } -+ -+ switch(msg->src.format) -+ { -+ case RK_FORMAT_YCbCr_420_P : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); -+ v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); -+ break; -+ case RK_FORMAT_YCbCr_420_SP : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); -+ break; -+ case RK_FORMAT_YCbCr_422_P : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); -+ v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); -+ break; -+ case RK_FORMAT_YCbCr_422_SP: -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); -+ break; -+ case RK_FORMAT_YCrCb_420_P : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); -+ v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); -+ break; -+ case RK_FORMAT_YCrCb_420_SP : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); -+ break; -+ case RK_FORMAT_YCrCb_422_P : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); -+ v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); -+ break; -+ case RK_FORMAT_YCrCb_422_SP: -+ y_addr = msg->src.yrgb_addr + yp*stride + xp; -+ u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); -+ break; -+ default : -+ y_addr = msg->src.yrgb_addr + yp*stride + xp*pixel_width; -+ break; -+ } -+ -+ *bRGA_SRC_Y_MST = y_addr; -+ *bRGA_SRC_CB_MST = u_addr; -+ *bRGA_SRC_CR_MST = v_addr; -+ } -+ -+ /*dst info*/ -+ pixel_width = RGA_pixel_width_init(msg->dst.format); -+ stride = (msg->dst.vir_w * pixel_width + 3) & (~3); -+ *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (tile->dst_ctrl.y_off * stride) + (tile->dst_ctrl.x_off * pixel_width); -+ *bRGA_DST_CTR_INFO = (tile->dst_ctrl.w) | ((tile->dst_ctrl.h) << 16); -+ -+ *bRGA_DST_CTR_INFO |= ((1<<29) | (1<<28)); -+} -+ -+ -+ -+ -+/************************************************************* -+Func: -+ RGA_set_color_palette_reg_info -+Description: -+ fill color palette process some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+ -+static void -+RGA_set_color_palette_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_SRC_Y_MST; -+ u32 p; -+ s16 x_off, y_off; -+ u16 src_stride; -+ u8 shift; -+ u16 sw, byte_num; -+ -+ x_off = msg->src.x_offset; -+ y_off = msg->src.y_offset; -+ -+ sw = msg->src.vir_w; -+ shift = 3 - (msg->palette_mode & 3); -+ byte_num = sw >> shift; -+ src_stride = (byte_num + 3) & (~3); -+ -+ p = msg->src.yrgb_addr; -+ p = p + (x_off>>shift) + y_off*src_stride; -+ -+ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); -+ *bRGA_SRC_Y_MST = (u32)p; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_color_fill_reg_info -+Description: -+ fill color fill process some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+static void -+RGA_set_color_fill_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ -+ u32 *bRGA_CP_GR_A; -+ u32 *bRGA_CP_GR_B; -+ u32 *bRGA_CP_GR_G; -+ u32 *bRGA_CP_GR_R; -+ -+ u32 *bRGA_PAT_CON; -+ -+ bRGA_CP_GR_A = (u32 *)(base + RGA_CP_GR_A_OFFSET); -+ bRGA_CP_GR_B = (u32 *)(base + RGA_CP_GR_B_OFFSET); -+ bRGA_CP_GR_G = (u32 *)(base + RGA_CP_GR_G_OFFSET); -+ bRGA_CP_GR_R = (u32 *)(base + RGA_CP_GR_R_OFFSET); -+ -+ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); -+ -+ *bRGA_CP_GR_A = (msg->gr_color.gr_x_a & 0xffff) | (msg->gr_color.gr_y_a << 16); -+ *bRGA_CP_GR_B = (msg->gr_color.gr_x_b & 0xffff) | (msg->gr_color.gr_y_b << 16); -+ *bRGA_CP_GR_G = (msg->gr_color.gr_x_g & 0xffff) | (msg->gr_color.gr_y_g << 16); -+ *bRGA_CP_GR_R = (msg->gr_color.gr_x_r & 0xffff) | (msg->gr_color.gr_y_r << 16); -+ -+ *bRGA_PAT_CON = (msg->pat.vir_w-1) | ((msg->pat.vir_h-1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); -+ -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_line_drawing_reg_info -+Description: -+ fill line drawing process some relate reg bit -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ ++RGA_set_pat(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_PAT_CON; ++ u32 *bRGA_PAT_START_POINT; ++ u32 reg = 0; ++ ++ bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); ++ ++ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); ++ ++ *bRGA_PAT_START_POINT = (msg->pat.act_w * msg->pat.y_offset) + msg->pat.x_offset; ++ ++ reg = (msg->pat.act_w - 1) | ((msg->pat.act_h - 1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); ++ *bRGA_PAT_CON = reg; ++ ++ return 0; ++} ++ ++ ++ ++ ++/************************************************************* ++Func: ++ RGA_set_bitblt_reg_info ++Description: ++ fill bitblt mode relate ren info ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++RGA_set_bitblt_reg_info(u8 *base, const struct rga_req * msg, TILE_INFO *tile) ++{ ++ u32 *bRGA_SRC_Y_MST; ++ u32 *bRGA_SRC_CB_MST; ++ u32 *bRGA_SRC_CR_MST; ++ u32 *bRGA_SRC_X_PARA; ++ u32 *bRGA_SRC_Y_PARA; ++ u32 *bRGA_SRC_TILE_XINFO; ++ u32 *bRGA_SRC_TILE_YINFO; ++ u32 *bRGA_SRC_TILE_H_INCR; ++ u32 *bRGA_SRC_TILE_V_INCR; ++ u32 *bRGA_SRC_TILE_OFFSETX; ++ u32 *bRGA_SRC_TILE_OFFSETY; ++ ++ u32 *bRGA_DST_MST; ++ u32 *bRGA_DST_CTR_INFO; ++ ++ s32 m0, m1, m2, m3; ++ s32 pos[8]; ++ //s32 x_dx, x_dy, y_dx, y_dy; ++ s32 xmin, xmax, ymin, ymax; ++ s32 xp, yp; ++ u32 y_addr, u_addr, v_addr; ++ u32 pixel_width, stride; ++ ++ u_addr = v_addr = 0; ++ ++ /* src info */ ++ ++ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); ++ bRGA_SRC_CB_MST = (u32 *)(base + RGA_SRC_CB_MST_OFFSET); ++ bRGA_SRC_CR_MST = (u32 *)(base + RGA_SRC_CR_MST_OFFSET); ++ ++ bRGA_SRC_X_PARA = (u32 *)(base + RGA_SRC_X_PARA_OFFSET); ++ bRGA_SRC_Y_PARA = (u32 *)(base + RGA_SRC_Y_PARA_OFFSET); ++ ++ bRGA_SRC_TILE_XINFO = (u32 *)(base + RGA_SRC_TILE_XINFO_OFFSET); ++ bRGA_SRC_TILE_YINFO = (u32 *)(base + RGA_SRC_TILE_YINFO_OFFSET); ++ bRGA_SRC_TILE_H_INCR = (u32 *)(base + RGA_SRC_TILE_H_INCR_OFFSET); ++ bRGA_SRC_TILE_V_INCR = (u32 *)(base + RGA_SRC_TILE_V_INCR_OFFSET); ++ bRGA_SRC_TILE_OFFSETX = (u32 *)(base + RGA_SRC_TILE_OFFSETX_OFFSET); ++ bRGA_SRC_TILE_OFFSETY = (u32 *)(base + RGA_SRC_TILE_OFFSETY_OFFSET); ++ ++ bRGA_DST_MST = (u32 *)(base + RGA_DST_MST_OFFSET); ++ bRGA_DST_CTR_INFO = (u32 *)(base + RGA_DST_CTR_INFO_OFFSET); ++ ++ /* Matrix reg fill */ ++ m0 = (s32)(tile->matrix[0] >> 18); ++ m1 = (s32)(tile->matrix[1] >> 18); ++ m2 = (s32)(tile->matrix[2] >> 18); ++ m3 = (s32)(tile->matrix[3] >> 18); ++ ++ *bRGA_SRC_X_PARA = (m0 & 0xffff) | (m2 << 16); ++ *bRGA_SRC_Y_PARA = (m1 & 0xffff) | (m3 << 16); ++ ++ /* src tile information setting */ ++ if(msg->rotate_mode != 0)//add by hxx,2011.7.12,for rtl0707,when line scanning ,do not calc src tile info ++ { ++ *bRGA_SRC_TILE_XINFO = (tile->tile_start_x_coor & 0xffff) | (tile->tile_w << 16); ++ *bRGA_SRC_TILE_YINFO = (tile->tile_start_y_coor & 0xffff) | (tile->tile_h << 16); ++ ++ *bRGA_SRC_TILE_H_INCR = ((tile->x_dx) & 0xffff) | ((tile->x_dy) << 16); ++ *bRGA_SRC_TILE_V_INCR = ((tile->y_dx) & 0xffff) | ((tile->y_dy) << 16); ++ ++ *bRGA_SRC_TILE_OFFSETX = tile->tile_xoff; ++ *bRGA_SRC_TILE_OFFSETY = tile->tile_yoff; ++ } ++ ++ pixel_width = RGA_pixel_width_init(msg->src.format); ++ ++ stride = ((msg->src.vir_w * pixel_width) + 3) & (~3); ++ ++ if ((msg->rotate_mode == 1)||(msg->rotate_mode == 2)||(msg->rotate_mode == 3)) ++ { ++ pos[0] = tile->tile_start_x_coor<<8; ++ pos[1] = tile->tile_start_y_coor<<8; ++ ++ pos[2] = pos[0]; ++ pos[3] = pos[1] + tile->tile_h; ++ ++ pos[4] = pos[0] + tile->tile_w; ++ pos[5] = pos[1] + tile->tile_h; ++ ++ pos[6] = pos[0] + tile->tile_w; ++ pos[7] = pos[1]; ++ ++ pos[0] >>= 11; ++ pos[1] >>= 11; ++ ++ pos[2] >>= 11; ++ pos[3] >>= 11; ++ ++ pos[4] >>= 11; ++ pos[5] >>= 11; ++ ++ pos[6] >>= 11; ++ pos[7] >>= 11; ++ ++ xmax = (MAX(MAX(MAX(pos[0], pos[2]), pos[4]), pos[6]) + 1); ++ xmin = (MIN(MIN(MIN(pos[0], pos[2]), pos[4]), pos[6])); ++ ++ ymax = (MAX(MAX(MAX(pos[1], pos[3]), pos[5]), pos[7]) + 1); ++ ymin = (MIN(MIN(MIN(pos[1], pos[3]), pos[5]), pos[7])); ++ ++ xp = xmin + msg->src.x_offset; ++ yp = ymin + msg->src.y_offset; ++ ++ if (!((xmax < 0)||(xmin > msg->src.act_w - 1)||(ymax < 0)||(ymin > msg->src.act_h - 1))) ++ { ++ xp = CLIP(xp, msg->src.x_offset, msg->src.x_offset + msg->src.act_w - 1); ++ yp = CLIP(yp, msg->src.y_offset, msg->src.y_offset + msg->src.act_h - 1); ++ } ++ ++ switch(msg->src.format) ++ { ++ case RK_FORMAT_YCbCr_420_P : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); ++ v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); ++ break; ++ case RK_FORMAT_YCbCr_420_SP : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); ++ break; ++ case RK_FORMAT_YCbCr_422_P : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); ++ v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); ++ break; ++ case RK_FORMAT_YCbCr_422_SP: ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); ++ break; ++ case RK_FORMAT_YCrCb_420_P : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp>>1)*(stride>>1) + (xp>>1); ++ v_addr = msg->src.v_addr + (yp>>1)*(stride>>1) + (xp>>1); ++ break; ++ case RK_FORMAT_YCrCb_420_SP : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp>>1)*stride + ((xp>>1)<<1); ++ break; ++ case RK_FORMAT_YCrCb_422_P : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + (yp)*(stride>>1) + (xp>>1); ++ v_addr = msg->src.v_addr + (yp)*(stride>>1) + (xp>>1); ++ break; ++ case RK_FORMAT_YCrCb_422_SP: ++ y_addr = msg->src.yrgb_addr + yp*stride + xp; ++ u_addr = msg->src.uv_addr + yp*stride + ((xp>>1)<<1); ++ break; ++ default : ++ y_addr = msg->src.yrgb_addr + yp*stride + xp*pixel_width; ++ break; ++ } ++ ++ *bRGA_SRC_Y_MST = y_addr; ++ *bRGA_SRC_CB_MST = u_addr; ++ *bRGA_SRC_CR_MST = v_addr; ++ } ++ ++ /*dst info*/ ++ pixel_width = RGA_pixel_width_init(msg->dst.format); ++ stride = (msg->dst.vir_w * pixel_width + 3) & (~3); ++ *bRGA_DST_MST = (u32)msg->dst.yrgb_addr + (tile->dst_ctrl.y_off * stride) + (tile->dst_ctrl.x_off * pixel_width); ++ *bRGA_DST_CTR_INFO = (tile->dst_ctrl.w) | ((tile->dst_ctrl.h) << 16); ++ ++ *bRGA_DST_CTR_INFO |= ((1<<29) | (1<<28)); ++} ++ ++ ++ ++ ++/************************************************************* ++Func: ++ RGA_set_color_palette_reg_info ++Description: ++ fill color palette process some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++ ++static void ++RGA_set_color_palette_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_SRC_Y_MST; ++ u32 p; ++ s16 x_off, y_off; ++ u16 src_stride; ++ u8 shift; ++ u16 sw, byte_num; ++ ++ x_off = msg->src.x_offset; ++ y_off = msg->src.y_offset; ++ ++ sw = msg->src.vir_w; ++ shift = 3 - (msg->palette_mode & 3); ++ byte_num = sw >> shift; ++ src_stride = (byte_num + 3) & (~3); ++ ++ p = msg->src.yrgb_addr; ++ p = p + (x_off>>shift) + y_off*src_stride; ++ ++ bRGA_SRC_Y_MST = (u32 *)(base + RGA_SRC_Y_MST_OFFSET); ++ *bRGA_SRC_Y_MST = (u32)p; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_color_fill_reg_info ++Description: ++ fill color fill process some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++static void ++RGA_set_color_fill_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ ++ u32 *bRGA_CP_GR_A; ++ u32 *bRGA_CP_GR_B; ++ u32 *bRGA_CP_GR_G; ++ u32 *bRGA_CP_GR_R; ++ ++ u32 *bRGA_PAT_CON; ++ ++ bRGA_CP_GR_A = (u32 *)(base + RGA_CP_GR_A_OFFSET); ++ bRGA_CP_GR_B = (u32 *)(base + RGA_CP_GR_B_OFFSET); ++ bRGA_CP_GR_G = (u32 *)(base + RGA_CP_GR_G_OFFSET); ++ bRGA_CP_GR_R = (u32 *)(base + RGA_CP_GR_R_OFFSET); ++ ++ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); ++ ++ *bRGA_CP_GR_A = (msg->gr_color.gr_x_a & 0xffff) | (msg->gr_color.gr_y_a << 16); ++ *bRGA_CP_GR_B = (msg->gr_color.gr_x_b & 0xffff) | (msg->gr_color.gr_y_b << 16); ++ *bRGA_CP_GR_G = (msg->gr_color.gr_x_g & 0xffff) | (msg->gr_color.gr_y_g << 16); ++ *bRGA_CP_GR_R = (msg->gr_color.gr_x_r & 0xffff) | (msg->gr_color.gr_y_r << 16); ++ ++ *bRGA_PAT_CON = (msg->pat.vir_w-1) | ((msg->pat.vir_h-1) << 8) | (msg->pat.x_offset << 16) | (msg->pat.y_offset << 24); ++ ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_line_drawing_reg_info ++Description: ++ fill line drawing process some relate reg bit ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ + +static s32 RGA_set_line_drawing_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_LINE_DRAW; -+ u32 *bRGA_DST_VIR_INFO; -+ u32 *bRGA_LINE_DRAW_XY_INFO; -+ u32 *bRGA_LINE_DRAW_WIDTH; -+ u32 *bRGA_LINE_DRAWING_COLOR; -+ u32 *bRGA_LINE_DRAWING_MST; -+ -+ u32 reg = 0; -+ -+ s16 x_width, y_width; -+ u16 abs_x, abs_y, delta; -+ u16 stride; -+ u8 pw; -+ u32 start_addr; -+ u8 line_dir, dir_major, dir_semi_major; -+ u16 major_width; -+ -+ bRGA_LINE_DRAW = (u32 *)(base + RGA_LINE_DRAW_OFFSET); -+ bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); -+ bRGA_LINE_DRAW_XY_INFO = (u32 *)(base + RGA_LINE_DRAW_XY_INFO_OFFSET); -+ bRGA_LINE_DRAW_WIDTH = (u32 *)(base + RGA_LINE_DRAWING_WIDTH_OFFSET); -+ bRGA_LINE_DRAWING_COLOR = (u32 *)(base + RGA_LINE_DRAWING_COLOR_OFFSET); -+ bRGA_LINE_DRAWING_MST = (u32 *)(base + RGA_LINE_DRAWING_MST_OFFSET); -+ -+ pw = RGA_pixel_width_init(msg->dst.format); -+ -+ stride = (msg->dst.vir_w * pw + 3) & (~3); -+ -+ start_addr = msg->dst.yrgb_addr -+ + (msg->line_draw_info.start_point.y * stride) -+ + (msg->line_draw_info.start_point.x * pw); -+ -+ x_width = msg->line_draw_info.start_point.x - msg->line_draw_info.end_point.x; -+ y_width = msg->line_draw_info.start_point.y - msg->line_draw_info.end_point.y; -+ -+ abs_x = abs(x_width); -+ abs_y = abs(y_width); -+ -+ if (abs_x >= abs_y) -+ { -+ if (y_width > 0) -+ dir_semi_major = 1; -+ else -+ dir_semi_major = 0; -+ -+ if (x_width > 0) -+ dir_major = 1; -+ else -+ dir_major = 0; -+ -+ if((abs_x == 0)||(abs_y == 0)) -+ delta = 0; -+ else -+ delta = (abs_y<<12)/abs_x; -+ -+ if (delta >> 12) -+ delta -= 1; -+ -+ major_width = abs_x; -+ line_dir = 0; -+ } -+ else -+ { -+ if (x_width > 0) -+ dir_semi_major = 1; -+ else -+ dir_semi_major = 0; -+ -+ if (y_width > 0) -+ dir_major = 1; -+ else -+ dir_major = 0; -+ -+ delta = (abs_x<<12)/abs_y; -+ major_width = abs_y; -+ line_dir = 1; -+ } -+ -+ reg = (reg & (~m_RGA_LINE_DRAW_MAJOR_WIDTH)) | (s_RGA_LINE_DRAW_MAJOR_WIDTH(major_width)); -+ reg = (reg & (~m_RGA_LINE_DRAW_LINE_DIRECTION)) | (s_RGA_LINE_DRAW_LINE_DIRECTION(line_dir)); -+ reg = (reg & (~m_RGA_LINE_DRAW_LINE_WIDTH)) | (s_RGA_LINE_DRAW_LINE_WIDTH(msg->line_draw_info.line_width - 1)); -+ reg = (reg & (~m_RGA_LINE_DRAW_INCR_VALUE)) | (s_RGA_LINE_DRAW_INCR_VALUE(delta)); -+ reg = (reg & (~m_RGA_LINE_DRAW_DIR_SEMI_MAJOR)) | (s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(dir_semi_major)); -+ reg = (reg & (~m_RGA_LINE_DRAW_DIR_MAJOR)) | (s_RGA_LINE_DRAW_DIR_MAJOR(dir_major)); -+ reg = (reg & (~m_RGA_LINE_DRAW_LAST_POINT)) | (s_RGA_LINE_DRAW_LAST_POINT(msg->line_draw_info.flag >> 1)); -+ reg = (reg & (~m_RGA_LINE_DRAW_ANTI_ALISING)) | (s_RGA_LINE_DRAW_ANTI_ALISING(msg->line_draw_info.flag)); -+ -+ *bRGA_LINE_DRAW = reg; -+ -+ reg = (msg->line_draw_info.start_point.x & 0xfff) | ((msg->line_draw_info.start_point.y & 0xfff) << 16); -+ *bRGA_LINE_DRAW_XY_INFO = reg; -+ -+ *bRGA_LINE_DRAW_WIDTH = msg->dst.vir_w; -+ -+ *bRGA_LINE_DRAWING_COLOR = msg->line_draw_info.color; -+ -+ *bRGA_LINE_DRAWING_MST = (u32)start_addr; -+ -+ return 0; -+} -+ -+ ++{ ++ u32 *bRGA_LINE_DRAW; ++ u32 *bRGA_DST_VIR_INFO; ++ u32 *bRGA_LINE_DRAW_XY_INFO; ++ u32 *bRGA_LINE_DRAW_WIDTH; ++ u32 *bRGA_LINE_DRAWING_COLOR; ++ u32 *bRGA_LINE_DRAWING_MST; ++ ++ u32 reg = 0; ++ ++ s16 x_width, y_width; ++ u16 abs_x, abs_y, delta; ++ u16 stride; ++ u8 pw; ++ u32 start_addr; ++ u8 line_dir, dir_major, dir_semi_major; ++ u16 major_width; ++ ++ bRGA_LINE_DRAW = (u32 *)(base + RGA_LINE_DRAW_OFFSET); ++ bRGA_DST_VIR_INFO = (u32 *)(base + RGA_DST_VIR_INFO_OFFSET); ++ bRGA_LINE_DRAW_XY_INFO = (u32 *)(base + RGA_LINE_DRAW_XY_INFO_OFFSET); ++ bRGA_LINE_DRAW_WIDTH = (u32 *)(base + RGA_LINE_DRAWING_WIDTH_OFFSET); ++ bRGA_LINE_DRAWING_COLOR = (u32 *)(base + RGA_LINE_DRAWING_COLOR_OFFSET); ++ bRGA_LINE_DRAWING_MST = (u32 *)(base + RGA_LINE_DRAWING_MST_OFFSET); ++ ++ pw = RGA_pixel_width_init(msg->dst.format); ++ ++ stride = (msg->dst.vir_w * pw + 3) & (~3); ++ ++ start_addr = msg->dst.yrgb_addr ++ + (msg->line_draw_info.start_point.y * stride) ++ + (msg->line_draw_info.start_point.x * pw); ++ ++ x_width = msg->line_draw_info.start_point.x - msg->line_draw_info.end_point.x; ++ y_width = msg->line_draw_info.start_point.y - msg->line_draw_info.end_point.y; ++ ++ abs_x = abs(x_width); ++ abs_y = abs(y_width); ++ ++ if (abs_x >= abs_y) ++ { ++ if (y_width > 0) ++ dir_semi_major = 1; ++ else ++ dir_semi_major = 0; ++ ++ if (x_width > 0) ++ dir_major = 1; ++ else ++ dir_major = 0; ++ ++ if((abs_x == 0)||(abs_y == 0)) ++ delta = 0; ++ else ++ delta = (abs_y<<12)/abs_x; ++ ++ if (delta >> 12) ++ delta -= 1; ++ ++ major_width = abs_x; ++ line_dir = 0; ++ } ++ else ++ { ++ if (x_width > 0) ++ dir_semi_major = 1; ++ else ++ dir_semi_major = 0; ++ ++ if (y_width > 0) ++ dir_major = 1; ++ else ++ dir_major = 0; ++ ++ delta = (abs_x<<12)/abs_y; ++ major_width = abs_y; ++ line_dir = 1; ++ } ++ ++ reg = (reg & (~m_RGA_LINE_DRAW_MAJOR_WIDTH)) | (s_RGA_LINE_DRAW_MAJOR_WIDTH(major_width)); ++ reg = (reg & (~m_RGA_LINE_DRAW_LINE_DIRECTION)) | (s_RGA_LINE_DRAW_LINE_DIRECTION(line_dir)); ++ reg = (reg & (~m_RGA_LINE_DRAW_LINE_WIDTH)) | (s_RGA_LINE_DRAW_LINE_WIDTH(msg->line_draw_info.line_width - 1)); ++ reg = (reg & (~m_RGA_LINE_DRAW_INCR_VALUE)) | (s_RGA_LINE_DRAW_INCR_VALUE(delta)); ++ reg = (reg & (~m_RGA_LINE_DRAW_DIR_SEMI_MAJOR)) | (s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(dir_semi_major)); ++ reg = (reg & (~m_RGA_LINE_DRAW_DIR_MAJOR)) | (s_RGA_LINE_DRAW_DIR_MAJOR(dir_major)); ++ reg = (reg & (~m_RGA_LINE_DRAW_LAST_POINT)) | (s_RGA_LINE_DRAW_LAST_POINT(msg->line_draw_info.flag >> 1)); ++ reg = (reg & (~m_RGA_LINE_DRAW_ANTI_ALISING)) | (s_RGA_LINE_DRAW_ANTI_ALISING(msg->line_draw_info.flag)); ++ ++ *bRGA_LINE_DRAW = reg; ++ ++ reg = (msg->line_draw_info.start_point.x & 0xfff) | ((msg->line_draw_info.start_point.y & 0xfff) << 16); ++ *bRGA_LINE_DRAW_XY_INFO = reg; ++ ++ *bRGA_LINE_DRAW_WIDTH = msg->dst.vir_w; ++ ++ *bRGA_LINE_DRAWING_COLOR = msg->line_draw_info.color; ++ ++ *bRGA_LINE_DRAWING_MST = (u32)start_addr; ++ ++ return 0; ++} ++ ++ +/*full*/ +static s32 +RGA_set_filter_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_BLUR_SHARP_INFO; -+ u32 reg = 0; -+ -+ bRGA_BLUR_SHARP_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); -+ -+ reg = *bRGA_BLUR_SHARP_INFO; -+ -+ reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_TYPE)) | (s_RGA_BLUR_SHARP_FILTER_TYPE(msg->bsfilter_flag & 3))); -+ reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_MODE)) | (s_RGA_BLUR_SHARP_FILTER_MODE(msg->bsfilter_flag >>2))); -+ -+ *bRGA_BLUR_SHARP_INFO = reg; -+ -+ return 0; -+} -+ -+ -+/*full*/ ++{ ++ u32 *bRGA_BLUR_SHARP_INFO; ++ u32 reg = 0; ++ ++ bRGA_BLUR_SHARP_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); ++ ++ reg = *bRGA_BLUR_SHARP_INFO; ++ ++ reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_TYPE)) | (s_RGA_BLUR_SHARP_FILTER_TYPE(msg->bsfilter_flag & 3))); ++ reg = ((reg & (~m_RGA_BLUR_SHARP_FILTER_MODE)) | (s_RGA_BLUR_SHARP_FILTER_MODE(msg->bsfilter_flag >>2))); ++ ++ *bRGA_BLUR_SHARP_INFO = reg; ++ ++ return 0; ++} ++ ++ ++/*full*/ +static s32 -+RGA_set_pre_scale_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_PRE_SCALE_INFO; -+ u32 reg = 0; -+ u32 h_ratio = 0; -+ u32 v_ratio = 0; -+ u32 ps_yuv_flag = 0; -+ u32 src_width, src_height; -+ u32 dst_width, dst_height; -+ -+ src_width = msg->src.act_w; -+ src_height = msg->src.act_h; -+ -+ dst_width = msg->dst.act_w; -+ dst_height = msg->dst.act_h; -+ -+ if((dst_width == 0) || (dst_height == 0)) -+ { -+ printk("pre scale reg info error ratio is divide zero\n"); -+ return -EINVAL; -+ } -+ -+ h_ratio = (src_width <<16) / dst_width; -+ v_ratio = (src_height<<16) / dst_height; -+ -+ if (h_ratio <= (1<<16)) -+ h_ratio = 0; -+ else if (h_ratio <= (2<<16)) -+ h_ratio = 1; -+ else if (h_ratio <= (4<<16)) -+ h_ratio = 2; -+ else if (h_ratio <= (8<<16)) -+ h_ratio = 3; -+ -+ if (v_ratio <= (1<<16)) -+ v_ratio = 0; -+ else if (v_ratio <= (2<<16)) -+ v_ratio = 1; -+ else if (v_ratio <= (4<<16)) -+ v_ratio = 2; -+ else if (v_ratio <= (8<<16)) -+ v_ratio = 3; -+ -+ if(msg->src.format == msg->dst.format) -+ ps_yuv_flag = 0; -+ else -+ ps_yuv_flag = 1; -+ -+ bRGA_PRE_SCALE_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); -+ -+ reg = *bRGA_PRE_SCALE_INFO; -+ reg = ((reg & (~m_RGA_PRE_SCALE_HOR_RATIO)) | (s_RGA_PRE_SCALE_HOR_RATIO((u8)h_ratio))); -+ reg = ((reg & (~m_RGA_PRE_SCALE_VER_RATIO)) | (s_RGA_PRE_SCALE_VER_RATIO((u8)v_ratio))); -+ reg = ((reg & (~m_RGA_PRE_SCALE_OUTPUT_FORMAT)) | (s_RGA_PRE_SCALE_OUTPUT_FORMAT(ps_yuv_flag))); -+ -+ *bRGA_PRE_SCALE_INFO = reg; -+ -+ return 0; -+} -+ -+ -+ ++RGA_set_pre_scale_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_PRE_SCALE_INFO; ++ u32 reg = 0; ++ u32 h_ratio = 0; ++ u32 v_ratio = 0; ++ u32 ps_yuv_flag = 0; ++ u32 src_width, src_height; ++ u32 dst_width, dst_height; ++ ++ src_width = msg->src.act_w; ++ src_height = msg->src.act_h; ++ ++ dst_width = msg->dst.act_w; ++ dst_height = msg->dst.act_h; ++ ++ if((dst_width == 0) || (dst_height == 0)) ++ { ++ printk("pre scale reg info error ratio is divide zero\n"); ++ return -EINVAL; ++ } ++ ++ h_ratio = (src_width <<16) / dst_width; ++ v_ratio = (src_height<<16) / dst_height; ++ ++ if (h_ratio <= (1<<16)) ++ h_ratio = 0; ++ else if (h_ratio <= (2<<16)) ++ h_ratio = 1; ++ else if (h_ratio <= (4<<16)) ++ h_ratio = 2; ++ else if (h_ratio <= (8<<16)) ++ h_ratio = 3; ++ ++ if (v_ratio <= (1<<16)) ++ v_ratio = 0; ++ else if (v_ratio <= (2<<16)) ++ v_ratio = 1; ++ else if (v_ratio <= (4<<16)) ++ v_ratio = 2; ++ else if (v_ratio <= (8<<16)) ++ v_ratio = 3; ++ ++ if(msg->src.format == msg->dst.format) ++ ps_yuv_flag = 0; ++ else ++ ps_yuv_flag = 1; ++ ++ bRGA_PRE_SCALE_INFO = (u32 *)(base + RGA_ALPHA_CON_OFFSET); ++ ++ reg = *bRGA_PRE_SCALE_INFO; ++ reg = ((reg & (~m_RGA_PRE_SCALE_HOR_RATIO)) | (s_RGA_PRE_SCALE_HOR_RATIO((u8)h_ratio))); ++ reg = ((reg & (~m_RGA_PRE_SCALE_VER_RATIO)) | (s_RGA_PRE_SCALE_VER_RATIO((u8)v_ratio))); ++ reg = ((reg & (~m_RGA_PRE_SCALE_OUTPUT_FORMAT)) | (s_RGA_PRE_SCALE_OUTPUT_FORMAT(ps_yuv_flag))); ++ ++ *bRGA_PRE_SCALE_INFO = reg; ++ ++ return 0; ++} ++ ++ ++ +/*full*/ +static int -+RGA_set_update_palette_table_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_LUT_MST; -+ -+ if (!msg->LUT_addr) { -+ return -1; -+ } -+ -+ bRGA_LUT_MST = (u32 *)(base + RGA_LUT_MST_OFFSET); -+ -+ *bRGA_LUT_MST = (u32)msg->LUT_addr; -+ -+ return 0; -+} -+ -+ -+ ++RGA_set_update_palette_table_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_LUT_MST; ++ ++ if (!msg->LUT_addr) { ++ return -1; ++ } ++ ++ bRGA_LUT_MST = (u32 *)(base + RGA_LUT_MST_OFFSET); ++ ++ *bRGA_LUT_MST = (u32)msg->LUT_addr; ++ ++ return 0; ++} ++ ++ ++ +/*full*/ +static int -+RGA_set_update_patten_buff_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *bRGA_PAT_MST; -+ u32 *bRGA_PAT_CON; -+ u32 *bRGA_PAT_START_POINT; -+ u32 reg = 0; -+ rga_img_info_t *pat; -+ -+ pat = (rga_img_info_t *)&msg->pat; -+ -+ bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); -+ bRGA_PAT_MST = (u32 *)(base + RGA_PAT_MST_OFFSET); -+ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); -+ -+ if ( !pat->yrgb_addr ) { -+ return -1; -+ } -+ *bRGA_PAT_MST = (u32)pat->yrgb_addr; -+ -+ if ((pat->vir_w > 256)||(pat->x_offset > 256)||(pat->y_offset > 256)) { -+ return -1; -+ } -+ *bRGA_PAT_START_POINT = (pat->vir_w * pat->y_offset) + pat->x_offset; -+ -+ reg = (pat->vir_w-1) | ((pat->vir_h-1) << 8) | (pat->x_offset << 16) | (pat->y_offset << 24); -+ *bRGA_PAT_CON = reg; -+ -+ return 0; -+} -+ -+ -+/************************************************************* -+Func: -+ RGA_set_mmu_ctrl_reg_info -+Description: -+ fill mmu relate some reg info -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ ++RGA_set_update_patten_buff_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ u32 *bRGA_PAT_MST; ++ u32 *bRGA_PAT_CON; ++ u32 *bRGA_PAT_START_POINT; ++ u32 reg = 0; ++ rga_img_info_t *pat; ++ ++ pat = (rga_img_info_t *)&msg->pat; ++ ++ bRGA_PAT_START_POINT = (u32 *)(base + RGA_PAT_START_POINT_OFFSET); ++ bRGA_PAT_MST = (u32 *)(base + RGA_PAT_MST_OFFSET); ++ bRGA_PAT_CON = (u32 *)(base + RGA_PAT_CON_OFFSET); ++ ++ if ( !pat->yrgb_addr ) { ++ return -1; ++ } ++ *bRGA_PAT_MST = (u32)pat->yrgb_addr; ++ ++ if ((pat->vir_w > 256)||(pat->x_offset > 256)||(pat->y_offset > 256)) { ++ return -1; ++ } ++ *bRGA_PAT_START_POINT = (pat->vir_w * pat->y_offset) + pat->x_offset; ++ ++ reg = (pat->vir_w-1) | ((pat->vir_h-1) << 8) | (pat->x_offset << 16) | (pat->y_offset << 24); ++ *bRGA_PAT_CON = reg; ++ ++ return 0; ++} ++ ++ ++/************************************************************* ++Func: ++ RGA_set_mmu_ctrl_reg_info ++Description: ++ fill mmu relate some reg info ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ + +static s32 -+RGA_set_mmu_ctrl_reg_info(u8 *base, const struct rga_req *msg) -+{ -+ u32 *RGA_MMU_TLB, *RGA_MMU_CTRL_ADDR; -+ u32 mmu_addr; -+ u8 TLB_size, mmu_enable, src_flag, dst_flag, CMD_flag; -+ u32 reg = 0; -+ -+ mmu_addr = (u32)msg->mmu_info.base_addr; -+ TLB_size = (msg->mmu_info.mmu_flag >> 4) & 0x3; -+ mmu_enable = msg->mmu_info.mmu_flag & 0x1; -+ -+ src_flag = (msg->mmu_info.mmu_flag >> 1) & 0x1; -+ dst_flag = (msg->mmu_info.mmu_flag >> 2) & 0x1; -+ CMD_flag = (msg->mmu_info.mmu_flag >> 3) & 0x1; -+ -+ RGA_MMU_TLB = (u32 *)(base + RGA_MMU_TLB_OFFSET); -+ RGA_MMU_CTRL_ADDR = (u32 *)(base + RGA_FADING_CON_OFFSET); -+ -+ reg = ((reg & (~m_RGA_MMU_CTRL_TLB_ADDR)) | s_RGA_MMU_CTRL_TLB_ADDR(mmu_addr)); -+ *RGA_MMU_TLB = reg; -+ -+ reg = *RGA_MMU_CTRL_ADDR; -+ reg = ((reg & (~m_RGA_MMU_CTRL_PAGE_TABLE_SIZE)) | s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(TLB_size)); -+ reg = ((reg & (~m_RGA_MMU_CTRL_MMU_ENABLE)) | s_RGA_MMU_CTRL_MMU_ENABLE(mmu_enable)); -+ reg = ((reg & (~m_RGA_MMU_CTRL_SRC_FLUSH)) | s_RGA_MMU_CTRL_SRC_FLUSH(1)); -+ reg = ((reg & (~m_RGA_MMU_CTRL_DST_FLUSH)) | s_RGA_MMU_CTRL_DST_FLUSH(1)); -+ reg = ((reg & (~m_RGA_MMU_CTRL_CMD_CHAN_FLUSH)) | s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(1)); -+ *RGA_MMU_CTRL_ADDR = reg; -+ -+ return 0; -+} -+ -+ -+ -+/************************************************************* -+Func: -+ RGA_gen_reg_info -+Description: -+ Generate RGA command reg list from rga_req struct. -+Author: -+ ZhangShengqin -+Date: -+ 20012-2-2 10:59:25 -+**************************************************************/ -+int -+RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base) -+{ -+ TILE_INFO tile; -+ -+ memset(base, 0x0, 28*4); -+ RGA_set_mode_ctrl(base, msg); -+ -+ switch(msg->render_mode) -+ { -+ case bitblt_mode : -+ RGA_set_alpha_rop(base, msg); -+ RGA_set_src(base, msg); -+ RGA_set_dst(base, msg); -+ RGA_set_color(base, msg); -+ RGA_set_fading(base, msg); -+ RGA_set_pat(base, msg); -+ matrix_cal(msg, &tile); -+ dst_ctrl_cal(msg, &tile); -+ src_tile_info_cal(msg, &tile); -+ RGA_set_bitblt_reg_info(base, msg, &tile); -+ break; -+ case color_palette_mode : -+ RGA_set_src(base, msg); -+ RGA_set_dst(base, msg); -+ RGA_set_color(base, msg); -+ RGA_set_color_palette_reg_info(base, msg); -+ break; -+ case color_fill_mode : -+ RGA_set_alpha_rop(base, msg); -+ RGA_set_dst(base, msg); -+ RGA_set_color(base, msg); -+ RGA_set_pat(base, msg); -+ RGA_set_color_fill_reg_info(base, msg); -+ break; -+ case line_point_drawing_mode : -+ RGA_set_alpha_rop(base, msg); -+ RGA_set_dst(base, msg); -+ RGA_set_color(base, msg); -+ RGA_set_line_drawing_reg_info(base, msg); -+ break; -+ case blur_sharp_filter_mode : -+ RGA_set_src(base, msg); -+ RGA_set_dst(base, msg); -+ RGA_set_filter_reg_info(base, msg); -+ break; -+ case pre_scaling_mode : -+ RGA_set_src(base, msg); -+ RGA_set_dst(base, msg); -+ if(RGA_set_pre_scale_reg_info(base, msg) == -EINVAL) -+ return -1; -+ break; -+ case update_palette_table_mode : -+ if (RGA_set_update_palette_table_reg_info(base, msg)) { -+ return -1; -+ } -+ break; -+ case update_patten_buff_mode: -+ if (RGA_set_update_patten_buff_reg_info(base, msg)){ -+ return -1; -+ } -+ -+ break; -+ } -+ -+ RGA_set_mmu_ctrl_reg_info(base, msg); -+ -+ return 0; -+} -+ -+ -+ ++RGA_set_mmu_ctrl_reg_info(u8 *base, const struct rga_req *msg) ++{ ++ u32 *RGA_MMU_TLB, *RGA_MMU_CTRL_ADDR; ++ u32 mmu_addr; ++ u8 TLB_size, mmu_enable, src_flag, dst_flag, CMD_flag; ++ u32 reg = 0; ++ ++ mmu_addr = (u32)msg->mmu_info.base_addr; ++ TLB_size = (msg->mmu_info.mmu_flag >> 4) & 0x3; ++ mmu_enable = msg->mmu_info.mmu_flag & 0x1; ++ ++ src_flag = (msg->mmu_info.mmu_flag >> 1) & 0x1; ++ dst_flag = (msg->mmu_info.mmu_flag >> 2) & 0x1; ++ CMD_flag = (msg->mmu_info.mmu_flag >> 3) & 0x1; ++ ++ RGA_MMU_TLB = (u32 *)(base + RGA_MMU_TLB_OFFSET); ++ RGA_MMU_CTRL_ADDR = (u32 *)(base + RGA_FADING_CON_OFFSET); ++ ++ reg = ((reg & (~m_RGA_MMU_CTRL_TLB_ADDR)) | s_RGA_MMU_CTRL_TLB_ADDR(mmu_addr)); ++ *RGA_MMU_TLB = reg; ++ ++ reg = *RGA_MMU_CTRL_ADDR; ++ reg = ((reg & (~m_RGA_MMU_CTRL_PAGE_TABLE_SIZE)) | s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(TLB_size)); ++ reg = ((reg & (~m_RGA_MMU_CTRL_MMU_ENABLE)) | s_RGA_MMU_CTRL_MMU_ENABLE(mmu_enable)); ++ reg = ((reg & (~m_RGA_MMU_CTRL_SRC_FLUSH)) | s_RGA_MMU_CTRL_SRC_FLUSH(1)); ++ reg = ((reg & (~m_RGA_MMU_CTRL_DST_FLUSH)) | s_RGA_MMU_CTRL_DST_FLUSH(1)); ++ reg = ((reg & (~m_RGA_MMU_CTRL_CMD_CHAN_FLUSH)) | s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(1)); ++ *RGA_MMU_CTRL_ADDR = reg; ++ ++ return 0; ++} ++ ++ ++ ++/************************************************************* ++Func: ++ RGA_gen_reg_info ++Description: ++ Generate RGA command reg list from rga_req struct. ++Author: ++ ZhangShengqin ++Date: ++ 20012-2-2 10:59:25 ++**************************************************************/ ++int ++RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base) ++{ ++ TILE_INFO tile; ++ ++ memset(base, 0x0, 28*4); ++ RGA_set_mode_ctrl(base, msg); ++ ++ switch(msg->render_mode) ++ { ++ case bitblt_mode : ++ RGA_set_alpha_rop(base, msg); ++ RGA_set_src(base, msg); ++ RGA_set_dst(base, msg); ++ RGA_set_color(base, msg); ++ RGA_set_fading(base, msg); ++ RGA_set_pat(base, msg); ++ matrix_cal(msg, &tile); ++ dst_ctrl_cal(msg, &tile); ++ src_tile_info_cal(msg, &tile); ++ RGA_set_bitblt_reg_info(base, msg, &tile); ++ break; ++ case color_palette_mode : ++ RGA_set_src(base, msg); ++ RGA_set_dst(base, msg); ++ RGA_set_color(base, msg); ++ RGA_set_color_palette_reg_info(base, msg); ++ break; ++ case color_fill_mode : ++ RGA_set_alpha_rop(base, msg); ++ RGA_set_dst(base, msg); ++ RGA_set_color(base, msg); ++ RGA_set_pat(base, msg); ++ RGA_set_color_fill_reg_info(base, msg); ++ break; ++ case line_point_drawing_mode : ++ RGA_set_alpha_rop(base, msg); ++ RGA_set_dst(base, msg); ++ RGA_set_color(base, msg); ++ RGA_set_line_drawing_reg_info(base, msg); ++ break; ++ case blur_sharp_filter_mode : ++ RGA_set_src(base, msg); ++ RGA_set_dst(base, msg); ++ RGA_set_filter_reg_info(base, msg); ++ break; ++ case pre_scaling_mode : ++ RGA_set_src(base, msg); ++ RGA_set_dst(base, msg); ++ if(RGA_set_pre_scale_reg_info(base, msg) == -EINVAL) ++ return -1; ++ break; ++ case update_palette_table_mode : ++ if (RGA_set_update_palette_table_reg_info(base, msg)) { ++ return -1; ++ } ++ break; ++ case update_patten_buff_mode: ++ if (RGA_set_update_patten_buff_reg_info(base, msg)){ ++ return -1; ++ } ++ ++ break; ++ } ++ ++ RGA_set_mmu_ctrl_reg_info(base, msg); ++ ++ return 0; ++} ++ ++ ++ diff --git a/drivers/video/rockchip/rga/rga_reg_info.h b/drivers/video/rockchip/rga/rga_reg_info.h new file mode 100644 index 000000000..565e8f72d @@ -1845327,472 +1845327,472 @@ index 000000000..565e8f72d +++ b/drivers/video/rockchip/rga/rga_reg_info.h @@ -0,0 +1,467 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __REG_INFO_H__ -+#define __REG_INFO_H__ -+ -+ -+//#include "chip_register.h" -+ -+//#include "rga_struct.h" -+#include "rga.h" -+ -+#ifndef MIN -+#define MIN(X, Y) ((X)<(Y)?(X):(Y)) -+#endif -+ -+#ifndef MAX -+#define MAX(X, Y) ((X)>(Y)?(X):(Y)) -+#endif -+ -+#ifndef ABS -+#define ABS(X) (((X) < 0) ? (-(X)) : (X)) -+#endif -+ -+#ifndef CLIP -+#define CLIP(x, a, b) ((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)) -+#endif -+ -+//RGA register map -+ -+//General Registers -+#define rRGA_SYS_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_SYS_CTRL)) -+#define rRGA_CMD_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_CMD_CTRL)) -+#define rRGA_CMD_ADDR (*(volatile uint32_t *)(RGA_BASE + RGA_CMD_ADDR)) -+#define rRGA_STATUS (*(volatile uint32_t *)(RGA_BASE + RGA_STATUS)) -+#define rRGA_INT (*(volatile uint32_t *)(RGA_BASE + RGA_INT)) -+#define rRGA_AXI_ID (*(volatile uint32_t *)(RGA_BASE + RGA_AXI_ID)) -+#define rRGA_MMU_STA_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_STA_CTRL)) -+#define rRGA_MMU_STA (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_STA)) -+ -+//Command code start -+#define rRGA_MODE_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MODE_CTRL)) -+ -+//Source Image Registers -+#define rRGA_SRC_Y_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_Y_MST)) -+#define rRGA_SRC_CB_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_CB_MST)) -+#define rRGA_MASK_READ_MST (*(volatile uint32_t *)(RGA_BASE + RGA_MASK_READ_MST)) //repeat -+#define rRGA_SRC_CR_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_CR_MST)) -+#define rRGA_SRC_VIR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_VIR_INFO)) -+#define rRGA_SRC_ACT_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_ACT_INFO)) -+#define rRGA_SRC_X_PARA (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_X_PARA)) -+#define rRGA_SRC_Y_PARA (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_Y_PARA)) -+#define rRGA_SRC_TILE_XINFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_XINFO)) -+#define rRGA_SRC_TILE_YINFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_YINFO)) -+#define rRGA_SRC_TILE_H_INCR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_H_INCR)) -+#define rRGA_SRC_TILE_V_INCR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_V_INCR)) -+#define rRGA_SRC_TILE_OFFSETX (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_OFFSETX)) -+#define rRGA_SRC_TILE_OFFSETY (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_OFFSETY)) -+#define rRGA_SRC_BG_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_BG_COLOR)) -+#define rRGA_SRC_FG_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_FG_COLOR)) -+#define rRGA_LINE_DRAWING_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAWING_COLOR)) //repeat -+#define rRGA_SRC_TR_COLOR0 (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TR_COLOR0)) -+#define rRGA_CP_GR_A (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_A)) //repeat -+#define rRGA_SRC_TR_COLOR1 (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TR_COLOR1)) -+#define rRGA_CP_GR_B (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_B)) //repeat -+ -+#define rRGA_LINE_DRAW (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAW)) -+#define rRGA_PAT_START_POINT (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_START_POINT)) //repeat -+ -+//Destination Image Registers -+#define rRGA_DST_MST (*(volatile uint32_t *)(RGA_BASE + RGA_DST_MST)) -+#define rRGA_LUT_MST (*(volatile uint32_t *)(RGA_BASE + RGA_LUT_MST)) //repeat -+#define rRGA_PAT_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_MST)) //repeat -+#define rRGA_LINE_DRAWING_MST (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAWING_MST)) //repeat -+ -+#define rRGA_DST_VIR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_DST_VIR_INFO)) -+ -+#define rRGA_DST_CTR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_DST_CTR_INFO)) -+#define rRGA_LINE_DRAW_XY_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAW_XY_INFO)) //repeat -+ -+//Alpha/ROP Registers -+#define rRGA_ALPHA_CON (*(volatile uint32_t *)(RGA_BASE + RGA_ALPHA_CON)) -+#define rRGA_FADING_CON (*(volatile uint32_t *)(RGA_BASE + RGA_FADING_CON)) -+ -+#define rRGA_PAT_CON (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_CON)) -+#define rRGA_DST_VIR_WIDTH_PIX (*(volatile uint32_t *)(RGA_BASE + RGA_DST_VIR_WIDTH_PIX)) //repeat -+ -+#define rRGA_ROP_CON0 (*(volatile uint32_t *)(RGA_BASE + RGA_ROP_CON0)) -+#define rRGA_CP_GR_G (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_G)) //repeat -+#define rRGA_PRESCL_CB_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PRESCL_CB_MST)) //repeat -+ -+#define rRGA_ROP_CON1 (*(volatile uint32_t *)(RGA_BASE + RGA_ROP_CON1)) -+#define rRGA_CP_GR_R (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_R)) //repeat -+#define rRGA_PRESCL_CR_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PRESCL_CR_MST)) //repeat -+ -+//MMU Register -+#define rRGA_MMU_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_CTRL)) -+ -+ -+ -+ -+//----------------------------------------------------------------- -+//reg detail definition -+//----------------------------------------------------------------- -+/*RGA_SYS_CTRL*/ -+#define m_RGA_SYS_CTRL_CMD_MODE ( 1<<2 ) -+#define m_RGA_SYS_CTRL_OP_ST_SLV ( 1<<1 ) -+#define m_RGA_sys_CTRL_SOFT_RESET ( 1<<0 ) -+ -+#define s_RGA_SYS_CTRL_CMD_MODE(x) ( (x&0x1)<<2 ) -+#define s_RGA_SYS_CTRL_OP_ST_SLV(x) ( (x&0x1)<<1 ) -+#define s_RGA_sys_CTRL_SOFT_RESET(x) ( (x&0x1)<<0 ) -+ -+ -+/*RGA_CMD_CTRL*/ -+#define m_RGA_CMD_CTRL_CMD_INCR_NUM ( 0x3ff<<3 ) -+#define m_RGA_CMD_CTRL_CMD_STOP_MODE ( 1<<2 ) -+#define m_RGA_CMD_CTRL_CMD_INCR_VALID ( 1<<1 ) -+#define m_RGA_CMD_CTRL_CMD_LINE_FET_ST ( 1<<0 ) -+ -+#define s_RGA_CMD_CTRL_CMD_INCR_NUM(x) ( (x&0x3ff)<<3 ) -+#define s_RGA_CMD_CTRL_CMD_STOP_MODE(x) ( (x&0x1)<<2 ) -+#define s_RGA_CMD_CTRL_CMD_INCR_VALID(x) ( (x&0x1)<<1 ) -+#define s_RGA_CMD_CTRL_CMD_LINE_FET_ST(x) ( (x*0x1)<<0 ) -+ -+ -+/*RGA_STATUS*/ -+#define m_RGA_CMD_STATUS_CMD_TOTAL_NUM ( 0xfff<<20 ) -+#define m_RGA_CMD_STATUS_NOW_CMD_NUM ( 0xfff<<8 ) -+#define m_RGA_CMD_STATUS_ENGINE_STATUS ( 1<<0 ) -+ -+ -+/*RGA_INT*/ -+#define m_RGA_INT_ALL_CMD_DONE_INT_EN ( 1<<10 ) -+#define m_RGA_INT_MMU_INT_EN ( 1<<9 ) -+#define m_RGA_INT_ERROR_INT_EN ( 1<<8 ) -+#define m_RGA_INT_NOW_CMD_DONE_INT_CLEAR ( 1<<7 ) -+#define m_RGA_INT_ALL_CMD_DONE_INT_CLEAR ( 1<<6 ) -+#define m_RGA_INT_MMU_INT_CLEAR ( 1<<5 ) -+#define m_RGA_INT_ERROR_INT_CLEAR ( 1<<4 ) -+#define m_RGA_INT_NOW_CMD_DONE_INT_FLAG ( 1<<3 ) -+#define m_RGA_INT_ALL_CMD_DONE_INT_FLAG ( 1<<2 ) -+#define m_RGA_INT_MMU_INT_FLAG ( 1<<1 ) -+#define m_RGA_INT_ERROR_INT_FLAG ( 1<<0 ) -+ -+#define s_RGA_INT_ALL_CMD_DONE_INT_EN(x) ( (x&0x1)<<10 ) -+#define s_RGA_INT_MMU_INT_EN(x) ( (x&0x1)<<9 ) -+#define s_RGA_INT_ERROR_INT_EN(x) ( (x&0x1)<<8 ) -+#define s_RGA_INT_NOW_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<7 ) -+#define s_RGA_INT_ALL_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<6 ) -+#define s_RGA_INT_MMU_INT_CLEAR(x) ( (x&0x1)<<5 ) -+#define s_RGA_INT_ERROR_INT_CLEAR(x) ( (x&0x1)<<4 ) -+ -+ -+/*RGA_AXI_ID*/ -+#define m_RGA_AXI_ID_MMU_READ ( 3<<30 ) -+#define m_RGA_AXI_ID_MMU_WRITE ( 3<<28 ) -+#define m_RGA_AXI_ID_MASK_READ ( 0xf<<24 ) -+#define m_RGA_AXI_ID_CMD_FET ( 0xf<<20 ) -+#define m_RGA_AXI_ID_DST_WRITE ( 0xf<<16 ) -+#define m_RGA_AXI_ID_DST_READ ( 0xf<<12 ) -+#define m_RGA_AXI_ID_SRC_CR_READ ( 0xf<<8 ) -+#define m_RGA_AXI_ID_SRC_CB_READ ( 0xf<<4 ) -+#define m_RGA_AXI_ID_SRC_Y_READ ( 0xf<<0 ) -+ -+#define s_RGA_AXI_ID_MMU_READ(x) ( (x&0x3)<<30 ) -+#define s_RGA_AXI_ID_MMU_WRITE(x) ( (x&0x3)<<28 ) -+#define s_RGA_AXI_ID_MASK_READ(x) ( (x&0xf)<<24 ) -+#define s_RGA_AXI_ID_CMD_FET(x) ( (x&0xf)<<20 ) -+#define s_RGA_AXI_ID_DST_WRITE(x) ( (x&0xf)<<16 ) -+#define s_RGA_AXI_ID_DST_READ(x) ( (x&0xf)<<12 ) -+#define s_RGA_AXI_ID_SRC_CR_READ(x) ( (x&0xf)<<8 ) -+#define s_RGA_AXI_ID_SRC_CB_READ(x) ( (x&0xf)<<4 ) -+#define s_RGA_AXI_ID_SRC_Y_READ(x) ( (x&0xf)<<0 ) -+ -+ -+/*RGA_MMU_STA_CTRL*/ -+#define m_RGA_MMU_STA_CTRL_TLB_STA_CLEAR ( 1<<3 ) -+#define m_RGA_MMU_STA_CTRL_TLB_STA_RESUME ( 1<<2 ) -+#define m_RGA_MMU_STA_CTRL_TLB_STA_PAUSE ( 1<<1 ) -+#define m_RGA_MMU_STA_CTRL_TLB_STA_EN ( 1<<0 ) -+ -+#define s_RGA_MMU_STA_CTRL_TLB_STA_CLEAR(x) ( (x&0x1)<<3 ) -+#define s_RGA_MMU_STA_CTRL_TLB_STA_RESUME(x) ( (x&0x1)<<2 ) -+#define s_RGA_MMU_STA_CTRL_TLB_STA_PAUSE(x) ( (x&0x1)<<1 ) -+#define s_RGA_MMU_STA_CTRL_TLB_STA_EN(x) ( (x&0x1)<<0 ) -+ -+ -+ -+/* RGA_MODE_CTRL */ -+#define m_RGA_MODE_CTRL_2D_RENDER_MODE ( 7<<0 ) -+#define m_RGA_MODE_CTRL_SRC_RGB_PACK ( 1<<3 ) -+#define m_RGA_MODE_CTRL_SRC_FORMAT ( 15<<4 ) -+#define m_RGA_MODE_CTRL_SRC_RB_SWAP ( 1<<8 ) -+#define m_RGA_MODE_CTRL_SRC_ALPHA_SWAP ( 1<<9 ) -+#define m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE ( 1<<10 ) -+#define m_RGA_MODE_CTRL_YUV2RGB_CON_MODE ( 3<<11 ) -+#define m_RGA_MODE_CTRL_SRC_TRANS_MODE (0x1f<<13 ) -+#define m_RGA_MODE_CTRL_SRC_TR_MODE ( 1<<13 ) -+#define m_RGA_MODE_CTRL_SRC_TR_R_EN ( 1<<14 ) -+#define m_RGA_MODE_CTRL_SRC_TR_G_EN ( 1<<15 ) -+#define m_RGA_MODE_CTRL_SRC_TR_B_EN ( 1<<16 ) -+#define m_RGA_MODE_CTRL_SRC_TR_A_EN ( 1<<17 ) -+#define m_RGA_MODE_CTRL_ROTATE_MODE ( 3<<18 ) -+#define m_RGA_MODE_CTRL_SCALE_MODE ( 3<<20 ) -+#define m_RGA_MODE_CTRL_PAT_SEL ( 1<<22 ) -+#define m_RGA_MODE_CTRL_DST_FORMAT ( 3<<23 ) -+#define m_RGA_MODE_CTRL_DST_RGB_PACK ( 1<<25 ) -+#define m_RGA_MODE_CTRL_DST_RB_SWAP ( 1<<26 ) -+#define m_RGA_MODE_CTRL_DST_ALPHA_SWAP ( 1<<27 ) -+#define m_RGA_MODE_CTRL_LUT_ENDIAN_MODE ( 1<<28 ) -+#define m_RGA_MODE_CTRL_CMD_INT_ENABLE ( 1<<29 ) -+#define m_RGA_MODE_CTRL_ZERO_MODE_ENABLE ( 1<<30 ) -+#define m_RGA_MODE_CTRL_DST_ALPHA_ENABLE ( 1<<30 ) -+ -+ -+ -+#define s_RGA_MODE_CTRL_2D_RENDER_MODE(x) ( (x&0x7)<<0 ) -+#define s_RGA_MODE_CTRL_SRC_RGB_PACK(x) ( (x&0x1)<<3 ) -+#define s_RGA_MODE_CTRL_SRC_FORMAT(x) ( (x&0xf)<<4 ) -+#define s_RGA_MODE_CTRL_SRC_RB_SWAP(x) ( (x&0x1)<<8 ) -+#define s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(x) ( (x&0x1)<<9 ) -+#define s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE(x) ( (x&0x1)<<10 ) -+#define s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(x) ( (x&0x3)<<11 ) -+#define s_RGA_MODE_CTRL_SRC_TRANS_MODE(x) ( (x&0x1f)<<13 ) -+#define s_RGA_MODE_CTRL_SRC_TR_MODE(x) ( (x&0x1)<<13 ) -+#define s_RGA_MODE_CTRL_SRC_TR_R_EN(x) ( (x&0x1)<<14 ) -+#define s_RGA_MODE_CTRL_SRC_TR_G_EN(x) ( (x&0x1)<<15 ) -+#define s_RGA_MODE_CTRL_SRC_TR_B_EN(x) ( (x&0x1)<<16 ) -+#define s_RGA_MODE_CTRL_SRC_TR_A_EN(x) ( (x&0x1)<<17 ) -+#define s_RGA_MODE_CTRL_ROTATE_MODE(x) ( (x&0x3)<<18 ) -+#define s_RGA_MODE_CTRL_SCALE_MODE(x) ( (x&0x3)<<20 ) -+#define s_RGA_MODE_CTRL_PAT_SEL(x) ( (x&0x1)<<22 ) -+#define s_RGA_MODE_CTRL_DST_FORMAT(x) ( (x&0x3)<<23 ) -+#define s_RGA_MODE_CTRL_DST_RGB_PACK(x) ( (x&0x1)<<25 ) -+#define s_RGA_MODE_CTRL_DST_RB_SWAP(x) ( (x&0x1)<<26 ) -+#define s_RGA_MODE_CTRL_DST_ALPHA_SWAP(x) ( (x&0x1)<<27 ) -+#define s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(x) ( (x&0x1)<<28 ) -+#define s_RGA_MODE_CTRL_CMD_INT_ENABLE(x) ( (x&0x1)<<29 ) -+#define s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(x) ( (x&0x1)<<30 ) -+#define s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(x) ( (x&0x1)<<31 ) -+ -+ -+ -+/* RGA_LINE_DRAW */ -+#define m_RGA_LINE_DRAW_MAJOR_WIDTH ( 0x7ff<<0 ) -+#define m_RGA_LINE_DRAW_LINE_DIRECTION ( 0x1<<11) -+#define m_RGA_LINE_DRAW_LINE_WIDTH ( 0xf<<12) -+#define m_RGA_LINE_DRAW_INCR_VALUE ( 0xfff<<16) -+#define m_RGA_LINE_DRAW_DIR_MAJOR ( 0x1<<28) -+#define m_RGA_LINE_DRAW_DIR_SEMI_MAJOR ( 0x1<<29) -+#define m_RGA_LINE_DRAW_LAST_POINT ( 0x1<<30) -+#define m_RGA_LINE_DRAW_ANTI_ALISING ( 0x1<<31) -+ -+#define s_RGA_LINE_DRAW_MAJOR_WIDTH(x) (((x)&0x7ff)<<0 ) -+#define s_RGA_LINE_DRAW_LINE_DIRECTION(x) ( ((x)&0x1)<<11) -+#define s_RGA_LINE_DRAW_LINE_WIDTH(x) ( ((x)&0xf)<<12) -+#define s_RGA_LINE_DRAW_INCR_VALUE(x) (((x)&0xfff)<<16) -+#define s_RGA_LINE_DRAW_DIR_MAJOR(x) ( ((x)&0x1)<<28) -+#define s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(x) ( ((x)&0x1)<<29) -+#define s_RGA_LINE_DRAW_LAST_POINT(x) ( ((x)&0x1)<<30) -+#define s_RGA_LINE_DRAW_ANTI_ALISING(x) ( ((x)&0x1)<<31) -+ -+ -+/* RGA_ALPHA_CON */ -+#define m_RGA_ALPHA_CON_ENABLE ( 0x1<<0 ) -+#define m_RGA_ALPHA_CON_A_OR_R_SEL ( 0x1<<1 ) -+#define m_RGA_ALPHA_CON_ALPHA_MODE ( 0x3<<2 ) -+#define m_RGA_ALPHA_CON_PD_MODE ( 0xf<<4 ) -+#define m_RGA_ALPHA_CON_SET_CONSTANT_VALUE (0xff<<8 ) -+#define m_RGA_ALPHA_CON_PD_M_SEL ( 0x1<<16) -+#define m_RGA_ALPHA_CON_FADING_ENABLE ( 0x1<<17) -+#define m_RGA_ALPHA_CON_ROP_MODE_SEL ( 0x3<<18) -+#define m_RGA_ALPHA_CON_CAL_MODE_SEL ( 0x1<<28) -+#define m_RGA_ALPHA_CON_DITHER_ENABLE ( 0x1<<29) -+#define m_RGA_ALPHA_CON_GRADIENT_CAL_MODE ( 0x1<<30) -+#define m_RGA_ALPHA_CON_AA_SEL ( 0x1<<31) -+ -+#define s_RGA_ALPHA_CON_ENABLE(x) ( (x&0x1)<<0 ) -+#define s_RGA_ALPHA_CON_A_OR_R_SEL(x) ( (x&0x1)<<1 ) -+#define s_RGA_ALPHA_CON_ALPHA_MODE(x) ( (x&0x3)<<2 ) -+#define s_RGA_ALPHA_CON_PD_MODE(x) ( (x&0xf)<<4 ) -+#define s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(x) ((x&0xff)<<8 ) -+#define s_RGA_ALPHA_CON_PD_M_SEL(x) ( (x&0x1)<<16) -+#define s_RGA_ALPHA_CON_FADING_ENABLE(x) ( (x&0x1)<<17) -+#define s_RGA_ALPHA_CON_ROP_MODE_SEL(x) ( (x&0x3)<<18) -+#define s_RGA_ALPHA_CON_CAL_MODE_SEL(x) ( (x&0x1)<<28) -+#define s_RGA_ALPHA_CON_DITHER_ENABLE(x) ( (x&0x1)<<29) -+#define s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(x) ( (x&0x1)<<30) -+#define s_RGA_ALPHA_CON_AA_SEL(x) ( (x&0x1)<<31) -+ -+ -+/* blur sharp mode */ -+#define m_RGA_BLUR_SHARP_FILTER_MODE ( 0x1<<25 ) -+#define m_RGA_BLUR_SHARP_FILTER_TYPE ( 0x3<<26 ) -+ -+#define s_RGA_BLUR_SHARP_FILTER_MODE(x) ( (x&0x1)<<25 ) -+#define s_RGA_BLUR_SHARP_FILTER_TYPE(x) ( (x&0x3)<<26 ) -+ -+ -+/* pre scale mode */ -+#define m_RGA_PRE_SCALE_HOR_RATIO ( 0x3 <<20 ) -+#define m_RGA_PRE_SCALE_VER_RATIO ( 0x3 <<22 ) -+#define m_RGA_PRE_SCALE_OUTPUT_FORMAT ( 0x1 <<24 ) -+ -+#define s_RGA_PRE_SCALE_HOR_RATIO(x) ( (x&0x3) <<20 ) -+#define s_RGA_PRE_SCALE_VER_RATIO(x) ( (x&0x3) <<22 ) -+#define s_RGA_PRE_SCALE_OUTPUT_FORMAT(x) ( (x&0x1) <<24 ) -+ -+ -+ -+/* RGA_MMU_CTRL*/ -+#define m_RGA_MMU_CTRL_TLB_ADDR ( 0xffffffff<<0) -+#define m_RGA_MMU_CTRL_PAGE_TABLE_SIZE ( 0x3<<4 ) -+#define m_RGA_MMU_CTRL_MMU_ENABLE ( 0x1<<0 ) -+#define m_RGA_MMU_CTRL_SRC_FLUSH ( 0x1<<1 ) -+#define m_RGA_MMU_CTRL_DST_FLUSH ( 0x1<<2 ) -+#define m_RGA_MMU_CTRL_CMD_CHAN_FLUSH ( 0x1<<3 ) -+ -+#define s_RGA_MMU_CTRL_TLB_ADDR(x) ((x&0xffffffff)) -+#define s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(x) ((x&0x3)<<4) -+#define s_RGA_MMU_CTRL_MMU_ENABLE(x) ((x&0x1)<<0) -+#define s_RGA_MMU_CTRL_SRC_FLUSH(x) ((x&0x1)<<1) -+#define s_RGA_MMU_CTRL_DST_FLUSH(x) ((x&0x1)<<2) -+#define s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(x) ((x&0x1)<<3) -+ -+#endif -+ -+/* -+#define RGA_MODE_CTRL_OFFSET 0x0 -+#define RGA_SRC_Y_MST_OFFSET 0x4 -+#define RGA_SRC_CB_MST_OFFSET 0x8 -+#define RGA_SRC_CR_MST_OFFSET 0xc -+#define RGA_SRC_VIR_INFO_OFFSET 0x10 -+#define RGA_SRC_ACT_INFO_OFFSET 0x14 -+#define RGA_SRC_X_PARA_OFFSET 0x18 -+#define RGA_SRC_Y_PARA_OFFSET 0x1c -+#define RGA_SRC_TILE_XINFO_OFFSET 0x20 -+#define RGA_SRC_TILE_YINFO_OFFSET 0x24 -+#define RGA_SRC_TILE_H_INCR_OFFSET 0x28 -+#define RGA_SRC_TILE_V_INCR_OFFSET 0x2c -+#define RGA_SRC_TILE_OFFSETX_OFFSET 0x30 -+#define RGA_SRC_TILE_OFFSETY_OFFSET 0x34 -+#define RGA_SRC_BG_COLOR_OFFSET 0x38 -+ -+#define RGA_SRC_FG_COLOR_OFFSET 0x3c -+#define RGA_LINE_DRAWING_COLOR_OFFSET 0x3c -+ -+#define RGA_SRC_TR_COLOR0_OFFSET 0x40 -+#define RGA_CP_GR_A_OFFSET 0x40 //repeat -+ -+#define RGA_SRC_TR_COLOR1_OFFSET 0x44 -+#define RGA_CP_GR_B_OFFSET 0x44 //repeat -+ -+#define RGA_LINE_DRAW_OFFSET 0x48 -+#define RGA_PAT_START_POINT_OFFSET 0x48 //repeat -+ -+#define RGA_DST_MST_OFFSET 0x4c -+#define RGA_LUT_MST_OFFSET 0x4c //repeat -+#define RGA_PAT_MST_OFFSET 0x4c //repeat -+#define RGA_LINE_DRAWING_MST_OFFSET 0x4c //repeat -+ -+#define RGA_DST_VIR_INFO_OFFSET 0x50 -+ -+#define RGA_DST_CTR_INFO_OFFSET 0x54 -+#define RGA_LINE_DRAW_XY_INFO_OFFSET 0x54 //repeat -+ -+#define RGA_ALPHA_CON_OFFSET 0x58 -+#define RGA_FADING_CON_OFFSET 0x5c -+ -+#define RGA_PAT_CON_OFFSET 0x60 -+#define RGA_LINE_DRAWING_WIDTH_OFFSET 0x60 //repeat -+ -+#define RGA_ROP_CON0_OFFSET 0x64 -+#define RGA_CP_GR_G_OFFSET 0x64 //repeat -+#define RGA_PRESCL_CB_MST_OFFSET 0x64 //repeat -+ -+#define RGA_ROP_CON1_OFFSET 0x68 -+#define RGA_CP_GR_R_OFFSET 0x68 //repeat -+#define RGA_PRESCL_CR_MST_OFFSET 0x68 //repeat -+ -+#define RGA_MMU_CTRL_OFFSET 0x6c -+ -+ -+#define RGA_SYS_CTRL_OFFSET 0x000 -+#define RGA_CMD_CTRL_OFFSET 0x004 -+#define RGA_CMD_ADDR_OFFSET 0x008 -+#define RGA_STATUS_OFFSET 0x00c -+#define RGA_INT_OFFSET 0x010 -+#define RGA_AXI_ID_OFFSET 0x014 -+#define RGA_MMU_STA_CTRL_OFFSET 0x018 -+#define RGA_MMU_STA_OFFSET 0x01c -+*/ -+//hxx -+ -+#define RGA_SYS_CTRL_OFFSET (RGA_SYS_CTRL-0x100) -+#define RGA_CMD_CTRL_OFFSET (RGA_CMD_CTRL-0x100) -+#define RGA_CMD_ADDR_OFFSET (RGA_CMD_ADDR-0x100) -+#define RGA_STATUS_OFFSET (RGA_STATUS-0x100) -+#define RGA_INT_OFFSET (RGA_INT-0x100) -+#define RGA_AXI_ID_OFFSET (RGA_AXI_ID-0x100) -+#define RGA_MMU_STA_CTRL_OFFSET (RGA_MMU_STA_CTRL-0x100) -+#define RGA_MMU_STA_OFFSET (RGA_MMU_STA-0x100) -+ -+#define RGA_MODE_CTRL_OFFSET (RGA_MODE_CTRL-0x100) -+#define RGA_SRC_Y_MST_OFFSET (RGA_SRC_Y_MST-0x100) -+#define RGA_SRC_CB_MST_OFFSET (RGA_SRC_CB_MST-0x100) -+#define RGA_SRC_CR_MST_OFFSET (RGA_SRC_CR_MST-0x100) -+#define RGA_SRC_VIR_INFO_OFFSET (RGA_SRC_VIR_INFO-0x100) -+#define RGA_SRC_ACT_INFO_OFFSET (RGA_SRC_ACT_INFO-0x100) -+#define RGA_SRC_X_PARA_OFFSET (RGA_SRC_X_PARA-0x100) -+#define RGA_SRC_Y_PARA_OFFSET (RGA_SRC_Y_PARA-0x100) -+#define RGA_SRC_TILE_XINFO_OFFSET (RGA_SRC_TILE_XINFO-0x100) -+#define RGA_SRC_TILE_YINFO_OFFSET (RGA_SRC_TILE_YINFO-0x100) -+#define RGA_SRC_TILE_H_INCR_OFFSET (RGA_SRC_TILE_H_INCR-0x100) -+#define RGA_SRC_TILE_V_INCR_OFFSET (RGA_SRC_TILE_V_INCR-0x100) -+#define RGA_SRC_TILE_OFFSETX_OFFSET (RGA_SRC_TILE_OFFSETX-0x100) -+#define RGA_SRC_TILE_OFFSETY_OFFSET (RGA_SRC_TILE_OFFSETY-0x100) -+#define RGA_SRC_BG_COLOR_OFFSET (RGA_SRC_BG_COLOR-0x100) -+ -+#define RGA_SRC_FG_COLOR_OFFSET (RGA_SRC_FG_COLOR-0x100) -+#define RGA_LINE_DRAWING_COLOR_OFFSET (RGA_LINE_DRAWING_COLOR-0x100) -+ -+#define RGA_SRC_TR_COLOR0_OFFSET (RGA_SRC_TR_COLOR0-0x100) -+#define RGA_CP_GR_A_OFFSET (RGA_CP_GR_A-0x100) //repeat -+ -+#define RGA_SRC_TR_COLOR1_OFFSET (RGA_SRC_TR_COLOR1-0x100) -+#define RGA_CP_GR_B_OFFSET (RGA_CP_GR_B-0x100) //repeat -+ -+#define RGA_LINE_DRAW_OFFSET (RGA_LINE_DRAW-0x100) -+#define RGA_PAT_START_POINT_OFFSET (RGA_PAT_START_POINT-0x100) //repeat -+ -+#define RGA_DST_MST_OFFSET (RGA_DST_MST-0x100) -+#define RGA_LUT_MST_OFFSET (RGA_LUT_MST-0x100) //repeat -+#define RGA_PAT_MST_OFFSET (RGA_PAT_MST-0x100) //repeat -+#define RGA_LINE_DRAWING_MST_OFFSET (RGA_LINE_DRAWING_MST-0x100) //repeat -+ -+#define RGA_DST_VIR_INFO_OFFSET (RGA_DST_VIR_INFO-0x100) -+ -+#define RGA_DST_CTR_INFO_OFFSET (RGA_DST_CTR_INFO-0x100) -+#define RGA_LINE_DRAW_XY_INFO_OFFSET (RGA_LINE_DRAW_XY_INFO-0x100) //repeat -+ -+#define RGA_ALPHA_CON_OFFSET (RGA_ALPHA_CON-0x100) -+ -+#define RGA_PAT_CON_OFFSET (RGA_PAT_CON-0x100) -+#define RGA_LINE_DRAWING_WIDTH_OFFSET (RGA_DST_VIR_WIDTH_PIX-0x100) //repeat -+ -+#define RGA_ROP_CON0_OFFSET (RGA_ROP_CON0-0x100) -+#define RGA_CP_GR_G_OFFSET (RGA_CP_GR_G-0x100) //repeat -+#define RGA_PRESCL_CB_MST_OFFSET (RGA_PRESCL_CB_MST-0x100) //repeat -+ -+#define RGA_ROP_CON1_OFFSET (RGA_ROP_CON1-0x100) -+#define RGA_CP_GR_R_OFFSET (RGA_CP_GR_R-0x100) //repeat -+#define RGA_PRESCL_CR_MST_OFFSET (RGA_PRESCL_CR_MST-0x100) //repeat -+ -+#define RGA_FADING_CON_OFFSET (RGA_FADING_CON-0x100) -+#define RGA_MMU_TLB_OFFSET (RGA_MMU_TBL-0x100) -+ -+#define RGA_YUV_OUT_CFG_OFFSET (RGA_YUV_OUT_CFG-0x100) -+#define RGA_DST_UV_MST_OFFSET (RGA_DST_UV_MST-0x100) -+ -+ -+ -+void matrix_cal(const struct rga_req *msg, TILE_INFO *tile); -+ -+ -+int RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base); -+uint8_t RGA_pixel_width_init(uint32_t format); -+ ++#ifndef __REG_INFO_H__ ++#define __REG_INFO_H__ ++ ++ ++//#include "chip_register.h" ++ ++//#include "rga_struct.h" ++#include "rga.h" ++ ++#ifndef MIN ++#define MIN(X, Y) ((X)<(Y)?(X):(Y)) ++#endif ++ ++#ifndef MAX ++#define MAX(X, Y) ((X)>(Y)?(X):(Y)) ++#endif ++ ++#ifndef ABS ++#define ABS(X) (((X) < 0) ? (-(X)) : (X)) ++#endif ++ ++#ifndef CLIP ++#define CLIP(x, a, b) ((x) < (a)) ? (a) : (((x) > (b)) ? (b) : (x)) ++#endif ++ ++//RGA register map ++ ++//General Registers ++#define rRGA_SYS_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_SYS_CTRL)) ++#define rRGA_CMD_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_CMD_CTRL)) ++#define rRGA_CMD_ADDR (*(volatile uint32_t *)(RGA_BASE + RGA_CMD_ADDR)) ++#define rRGA_STATUS (*(volatile uint32_t *)(RGA_BASE + RGA_STATUS)) ++#define rRGA_INT (*(volatile uint32_t *)(RGA_BASE + RGA_INT)) ++#define rRGA_AXI_ID (*(volatile uint32_t *)(RGA_BASE + RGA_AXI_ID)) ++#define rRGA_MMU_STA_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_STA_CTRL)) ++#define rRGA_MMU_STA (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_STA)) ++ ++//Command code start ++#define rRGA_MODE_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MODE_CTRL)) ++ ++//Source Image Registers ++#define rRGA_SRC_Y_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_Y_MST)) ++#define rRGA_SRC_CB_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_CB_MST)) ++#define rRGA_MASK_READ_MST (*(volatile uint32_t *)(RGA_BASE + RGA_MASK_READ_MST)) //repeat ++#define rRGA_SRC_CR_MST (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_CR_MST)) ++#define rRGA_SRC_VIR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_VIR_INFO)) ++#define rRGA_SRC_ACT_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_ACT_INFO)) ++#define rRGA_SRC_X_PARA (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_X_PARA)) ++#define rRGA_SRC_Y_PARA (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_Y_PARA)) ++#define rRGA_SRC_TILE_XINFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_XINFO)) ++#define rRGA_SRC_TILE_YINFO (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_YINFO)) ++#define rRGA_SRC_TILE_H_INCR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_H_INCR)) ++#define rRGA_SRC_TILE_V_INCR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_V_INCR)) ++#define rRGA_SRC_TILE_OFFSETX (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_OFFSETX)) ++#define rRGA_SRC_TILE_OFFSETY (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TILE_OFFSETY)) ++#define rRGA_SRC_BG_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_BG_COLOR)) ++#define rRGA_SRC_FG_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_FG_COLOR)) ++#define rRGA_LINE_DRAWING_COLOR (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAWING_COLOR)) //repeat ++#define rRGA_SRC_TR_COLOR0 (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TR_COLOR0)) ++#define rRGA_CP_GR_A (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_A)) //repeat ++#define rRGA_SRC_TR_COLOR1 (*(volatile uint32_t *)(RGA_BASE + RGA_SRC_TR_COLOR1)) ++#define rRGA_CP_GR_B (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_B)) //repeat ++ ++#define rRGA_LINE_DRAW (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAW)) ++#define rRGA_PAT_START_POINT (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_START_POINT)) //repeat ++ ++//Destination Image Registers ++#define rRGA_DST_MST (*(volatile uint32_t *)(RGA_BASE + RGA_DST_MST)) ++#define rRGA_LUT_MST (*(volatile uint32_t *)(RGA_BASE + RGA_LUT_MST)) //repeat ++#define rRGA_PAT_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_MST)) //repeat ++#define rRGA_LINE_DRAWING_MST (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAWING_MST)) //repeat ++ ++#define rRGA_DST_VIR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_DST_VIR_INFO)) ++ ++#define rRGA_DST_CTR_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_DST_CTR_INFO)) ++#define rRGA_LINE_DRAW_XY_INFO (*(volatile uint32_t *)(RGA_BASE + RGA_LINE_DRAW_XY_INFO)) //repeat ++ ++//Alpha/ROP Registers ++#define rRGA_ALPHA_CON (*(volatile uint32_t *)(RGA_BASE + RGA_ALPHA_CON)) ++#define rRGA_FADING_CON (*(volatile uint32_t *)(RGA_BASE + RGA_FADING_CON)) ++ ++#define rRGA_PAT_CON (*(volatile uint32_t *)(RGA_BASE + RGA_PAT_CON)) ++#define rRGA_DST_VIR_WIDTH_PIX (*(volatile uint32_t *)(RGA_BASE + RGA_DST_VIR_WIDTH_PIX)) //repeat ++ ++#define rRGA_ROP_CON0 (*(volatile uint32_t *)(RGA_BASE + RGA_ROP_CON0)) ++#define rRGA_CP_GR_G (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_G)) //repeat ++#define rRGA_PRESCL_CB_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PRESCL_CB_MST)) //repeat ++ ++#define rRGA_ROP_CON1 (*(volatile uint32_t *)(RGA_BASE + RGA_ROP_CON1)) ++#define rRGA_CP_GR_R (*(volatile uint32_t *)(RGA_BASE + RGA_CP_GR_R)) //repeat ++#define rRGA_PRESCL_CR_MST (*(volatile uint32_t *)(RGA_BASE + RGA_PRESCL_CR_MST)) //repeat ++ ++//MMU Register ++#define rRGA_MMU_CTRL (*(volatile uint32_t *)(RGA_BASE + RGA_MMU_CTRL)) ++ ++ ++ ++ ++//----------------------------------------------------------------- ++//reg detail definition ++//----------------------------------------------------------------- ++/*RGA_SYS_CTRL*/ ++#define m_RGA_SYS_CTRL_CMD_MODE ( 1<<2 ) ++#define m_RGA_SYS_CTRL_OP_ST_SLV ( 1<<1 ) ++#define m_RGA_sys_CTRL_SOFT_RESET ( 1<<0 ) ++ ++#define s_RGA_SYS_CTRL_CMD_MODE(x) ( (x&0x1)<<2 ) ++#define s_RGA_SYS_CTRL_OP_ST_SLV(x) ( (x&0x1)<<1 ) ++#define s_RGA_sys_CTRL_SOFT_RESET(x) ( (x&0x1)<<0 ) ++ ++ ++/*RGA_CMD_CTRL*/ ++#define m_RGA_CMD_CTRL_CMD_INCR_NUM ( 0x3ff<<3 ) ++#define m_RGA_CMD_CTRL_CMD_STOP_MODE ( 1<<2 ) ++#define m_RGA_CMD_CTRL_CMD_INCR_VALID ( 1<<1 ) ++#define m_RGA_CMD_CTRL_CMD_LINE_FET_ST ( 1<<0 ) ++ ++#define s_RGA_CMD_CTRL_CMD_INCR_NUM(x) ( (x&0x3ff)<<3 ) ++#define s_RGA_CMD_CTRL_CMD_STOP_MODE(x) ( (x&0x1)<<2 ) ++#define s_RGA_CMD_CTRL_CMD_INCR_VALID(x) ( (x&0x1)<<1 ) ++#define s_RGA_CMD_CTRL_CMD_LINE_FET_ST(x) ( (x*0x1)<<0 ) ++ ++ ++/*RGA_STATUS*/ ++#define m_RGA_CMD_STATUS_CMD_TOTAL_NUM ( 0xfff<<20 ) ++#define m_RGA_CMD_STATUS_NOW_CMD_NUM ( 0xfff<<8 ) ++#define m_RGA_CMD_STATUS_ENGINE_STATUS ( 1<<0 ) ++ ++ ++/*RGA_INT*/ ++#define m_RGA_INT_ALL_CMD_DONE_INT_EN ( 1<<10 ) ++#define m_RGA_INT_MMU_INT_EN ( 1<<9 ) ++#define m_RGA_INT_ERROR_INT_EN ( 1<<8 ) ++#define m_RGA_INT_NOW_CMD_DONE_INT_CLEAR ( 1<<7 ) ++#define m_RGA_INT_ALL_CMD_DONE_INT_CLEAR ( 1<<6 ) ++#define m_RGA_INT_MMU_INT_CLEAR ( 1<<5 ) ++#define m_RGA_INT_ERROR_INT_CLEAR ( 1<<4 ) ++#define m_RGA_INT_NOW_CMD_DONE_INT_FLAG ( 1<<3 ) ++#define m_RGA_INT_ALL_CMD_DONE_INT_FLAG ( 1<<2 ) ++#define m_RGA_INT_MMU_INT_FLAG ( 1<<1 ) ++#define m_RGA_INT_ERROR_INT_FLAG ( 1<<0 ) ++ ++#define s_RGA_INT_ALL_CMD_DONE_INT_EN(x) ( (x&0x1)<<10 ) ++#define s_RGA_INT_MMU_INT_EN(x) ( (x&0x1)<<9 ) ++#define s_RGA_INT_ERROR_INT_EN(x) ( (x&0x1)<<8 ) ++#define s_RGA_INT_NOW_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<7 ) ++#define s_RGA_INT_ALL_CMD_DONE_INT_CLEAR(x) ( (x&0x1)<<6 ) ++#define s_RGA_INT_MMU_INT_CLEAR(x) ( (x&0x1)<<5 ) ++#define s_RGA_INT_ERROR_INT_CLEAR(x) ( (x&0x1)<<4 ) ++ ++ ++/*RGA_AXI_ID*/ ++#define m_RGA_AXI_ID_MMU_READ ( 3<<30 ) ++#define m_RGA_AXI_ID_MMU_WRITE ( 3<<28 ) ++#define m_RGA_AXI_ID_MASK_READ ( 0xf<<24 ) ++#define m_RGA_AXI_ID_CMD_FET ( 0xf<<20 ) ++#define m_RGA_AXI_ID_DST_WRITE ( 0xf<<16 ) ++#define m_RGA_AXI_ID_DST_READ ( 0xf<<12 ) ++#define m_RGA_AXI_ID_SRC_CR_READ ( 0xf<<8 ) ++#define m_RGA_AXI_ID_SRC_CB_READ ( 0xf<<4 ) ++#define m_RGA_AXI_ID_SRC_Y_READ ( 0xf<<0 ) ++ ++#define s_RGA_AXI_ID_MMU_READ(x) ( (x&0x3)<<30 ) ++#define s_RGA_AXI_ID_MMU_WRITE(x) ( (x&0x3)<<28 ) ++#define s_RGA_AXI_ID_MASK_READ(x) ( (x&0xf)<<24 ) ++#define s_RGA_AXI_ID_CMD_FET(x) ( (x&0xf)<<20 ) ++#define s_RGA_AXI_ID_DST_WRITE(x) ( (x&0xf)<<16 ) ++#define s_RGA_AXI_ID_DST_READ(x) ( (x&0xf)<<12 ) ++#define s_RGA_AXI_ID_SRC_CR_READ(x) ( (x&0xf)<<8 ) ++#define s_RGA_AXI_ID_SRC_CB_READ(x) ( (x&0xf)<<4 ) ++#define s_RGA_AXI_ID_SRC_Y_READ(x) ( (x&0xf)<<0 ) ++ ++ ++/*RGA_MMU_STA_CTRL*/ ++#define m_RGA_MMU_STA_CTRL_TLB_STA_CLEAR ( 1<<3 ) ++#define m_RGA_MMU_STA_CTRL_TLB_STA_RESUME ( 1<<2 ) ++#define m_RGA_MMU_STA_CTRL_TLB_STA_PAUSE ( 1<<1 ) ++#define m_RGA_MMU_STA_CTRL_TLB_STA_EN ( 1<<0 ) ++ ++#define s_RGA_MMU_STA_CTRL_TLB_STA_CLEAR(x) ( (x&0x1)<<3 ) ++#define s_RGA_MMU_STA_CTRL_TLB_STA_RESUME(x) ( (x&0x1)<<2 ) ++#define s_RGA_MMU_STA_CTRL_TLB_STA_PAUSE(x) ( (x&0x1)<<1 ) ++#define s_RGA_MMU_STA_CTRL_TLB_STA_EN(x) ( (x&0x1)<<0 ) ++ ++ ++ ++/* RGA_MODE_CTRL */ ++#define m_RGA_MODE_CTRL_2D_RENDER_MODE ( 7<<0 ) ++#define m_RGA_MODE_CTRL_SRC_RGB_PACK ( 1<<3 ) ++#define m_RGA_MODE_CTRL_SRC_FORMAT ( 15<<4 ) ++#define m_RGA_MODE_CTRL_SRC_RB_SWAP ( 1<<8 ) ++#define m_RGA_MODE_CTRL_SRC_ALPHA_SWAP ( 1<<9 ) ++#define m_RGA_MODE_CTRL_SRC_UV_SWAP_MODE ( 1<<10 ) ++#define m_RGA_MODE_CTRL_YUV2RGB_CON_MODE ( 3<<11 ) ++#define m_RGA_MODE_CTRL_SRC_TRANS_MODE (0x1f<<13 ) ++#define m_RGA_MODE_CTRL_SRC_TR_MODE ( 1<<13 ) ++#define m_RGA_MODE_CTRL_SRC_TR_R_EN ( 1<<14 ) ++#define m_RGA_MODE_CTRL_SRC_TR_G_EN ( 1<<15 ) ++#define m_RGA_MODE_CTRL_SRC_TR_B_EN ( 1<<16 ) ++#define m_RGA_MODE_CTRL_SRC_TR_A_EN ( 1<<17 ) ++#define m_RGA_MODE_CTRL_ROTATE_MODE ( 3<<18 ) ++#define m_RGA_MODE_CTRL_SCALE_MODE ( 3<<20 ) ++#define m_RGA_MODE_CTRL_PAT_SEL ( 1<<22 ) ++#define m_RGA_MODE_CTRL_DST_FORMAT ( 3<<23 ) ++#define m_RGA_MODE_CTRL_DST_RGB_PACK ( 1<<25 ) ++#define m_RGA_MODE_CTRL_DST_RB_SWAP ( 1<<26 ) ++#define m_RGA_MODE_CTRL_DST_ALPHA_SWAP ( 1<<27 ) ++#define m_RGA_MODE_CTRL_LUT_ENDIAN_MODE ( 1<<28 ) ++#define m_RGA_MODE_CTRL_CMD_INT_ENABLE ( 1<<29 ) ++#define m_RGA_MODE_CTRL_ZERO_MODE_ENABLE ( 1<<30 ) ++#define m_RGA_MODE_CTRL_DST_ALPHA_ENABLE ( 1<<30 ) ++ ++ ++ ++#define s_RGA_MODE_CTRL_2D_RENDER_MODE(x) ( (x&0x7)<<0 ) ++#define s_RGA_MODE_CTRL_SRC_RGB_PACK(x) ( (x&0x1)<<3 ) ++#define s_RGA_MODE_CTRL_SRC_FORMAT(x) ( (x&0xf)<<4 ) ++#define s_RGA_MODE_CTRL_SRC_RB_SWAP(x) ( (x&0x1)<<8 ) ++#define s_RGA_MODE_CTRL_SRC_ALPHA_SWAP(x) ( (x&0x1)<<9 ) ++#define s_RGA_MODE_CTRL_SRC_UV_SWAP_MODE(x) ( (x&0x1)<<10 ) ++#define s_RGA_MODE_CTRL_YUV2RGB_CON_MODE(x) ( (x&0x3)<<11 ) ++#define s_RGA_MODE_CTRL_SRC_TRANS_MODE(x) ( (x&0x1f)<<13 ) ++#define s_RGA_MODE_CTRL_SRC_TR_MODE(x) ( (x&0x1)<<13 ) ++#define s_RGA_MODE_CTRL_SRC_TR_R_EN(x) ( (x&0x1)<<14 ) ++#define s_RGA_MODE_CTRL_SRC_TR_G_EN(x) ( (x&0x1)<<15 ) ++#define s_RGA_MODE_CTRL_SRC_TR_B_EN(x) ( (x&0x1)<<16 ) ++#define s_RGA_MODE_CTRL_SRC_TR_A_EN(x) ( (x&0x1)<<17 ) ++#define s_RGA_MODE_CTRL_ROTATE_MODE(x) ( (x&0x3)<<18 ) ++#define s_RGA_MODE_CTRL_SCALE_MODE(x) ( (x&0x3)<<20 ) ++#define s_RGA_MODE_CTRL_PAT_SEL(x) ( (x&0x1)<<22 ) ++#define s_RGA_MODE_CTRL_DST_FORMAT(x) ( (x&0x3)<<23 ) ++#define s_RGA_MODE_CTRL_DST_RGB_PACK(x) ( (x&0x1)<<25 ) ++#define s_RGA_MODE_CTRL_DST_RB_SWAP(x) ( (x&0x1)<<26 ) ++#define s_RGA_MODE_CTRL_DST_ALPHA_SWAP(x) ( (x&0x1)<<27 ) ++#define s_RGA_MODE_CTRL_LUT_ENDIAN_MODE(x) ( (x&0x1)<<28 ) ++#define s_RGA_MODE_CTRL_CMD_INT_ENABLE(x) ( (x&0x1)<<29 ) ++#define s_RGA_MODE_CTRL_ZERO_MODE_ENABLE(x) ( (x&0x1)<<30 ) ++#define s_RGA_MODE_CTRL_DST_ALPHA_ENABLE(x) ( (x&0x1)<<31 ) ++ ++ ++ ++/* RGA_LINE_DRAW */ ++#define m_RGA_LINE_DRAW_MAJOR_WIDTH ( 0x7ff<<0 ) ++#define m_RGA_LINE_DRAW_LINE_DIRECTION ( 0x1<<11) ++#define m_RGA_LINE_DRAW_LINE_WIDTH ( 0xf<<12) ++#define m_RGA_LINE_DRAW_INCR_VALUE ( 0xfff<<16) ++#define m_RGA_LINE_DRAW_DIR_MAJOR ( 0x1<<28) ++#define m_RGA_LINE_DRAW_DIR_SEMI_MAJOR ( 0x1<<29) ++#define m_RGA_LINE_DRAW_LAST_POINT ( 0x1<<30) ++#define m_RGA_LINE_DRAW_ANTI_ALISING ( 0x1<<31) ++ ++#define s_RGA_LINE_DRAW_MAJOR_WIDTH(x) (((x)&0x7ff)<<0 ) ++#define s_RGA_LINE_DRAW_LINE_DIRECTION(x) ( ((x)&0x1)<<11) ++#define s_RGA_LINE_DRAW_LINE_WIDTH(x) ( ((x)&0xf)<<12) ++#define s_RGA_LINE_DRAW_INCR_VALUE(x) (((x)&0xfff)<<16) ++#define s_RGA_LINE_DRAW_DIR_MAJOR(x) ( ((x)&0x1)<<28) ++#define s_RGA_LINE_DRAW_DIR_SEMI_MAJOR(x) ( ((x)&0x1)<<29) ++#define s_RGA_LINE_DRAW_LAST_POINT(x) ( ((x)&0x1)<<30) ++#define s_RGA_LINE_DRAW_ANTI_ALISING(x) ( ((x)&0x1)<<31) ++ ++ ++/* RGA_ALPHA_CON */ ++#define m_RGA_ALPHA_CON_ENABLE ( 0x1<<0 ) ++#define m_RGA_ALPHA_CON_A_OR_R_SEL ( 0x1<<1 ) ++#define m_RGA_ALPHA_CON_ALPHA_MODE ( 0x3<<2 ) ++#define m_RGA_ALPHA_CON_PD_MODE ( 0xf<<4 ) ++#define m_RGA_ALPHA_CON_SET_CONSTANT_VALUE (0xff<<8 ) ++#define m_RGA_ALPHA_CON_PD_M_SEL ( 0x1<<16) ++#define m_RGA_ALPHA_CON_FADING_ENABLE ( 0x1<<17) ++#define m_RGA_ALPHA_CON_ROP_MODE_SEL ( 0x3<<18) ++#define m_RGA_ALPHA_CON_CAL_MODE_SEL ( 0x1<<28) ++#define m_RGA_ALPHA_CON_DITHER_ENABLE ( 0x1<<29) ++#define m_RGA_ALPHA_CON_GRADIENT_CAL_MODE ( 0x1<<30) ++#define m_RGA_ALPHA_CON_AA_SEL ( 0x1<<31) ++ ++#define s_RGA_ALPHA_CON_ENABLE(x) ( (x&0x1)<<0 ) ++#define s_RGA_ALPHA_CON_A_OR_R_SEL(x) ( (x&0x1)<<1 ) ++#define s_RGA_ALPHA_CON_ALPHA_MODE(x) ( (x&0x3)<<2 ) ++#define s_RGA_ALPHA_CON_PD_MODE(x) ( (x&0xf)<<4 ) ++#define s_RGA_ALPHA_CON_SET_CONSTANT_VALUE(x) ((x&0xff)<<8 ) ++#define s_RGA_ALPHA_CON_PD_M_SEL(x) ( (x&0x1)<<16) ++#define s_RGA_ALPHA_CON_FADING_ENABLE(x) ( (x&0x1)<<17) ++#define s_RGA_ALPHA_CON_ROP_MODE_SEL(x) ( (x&0x3)<<18) ++#define s_RGA_ALPHA_CON_CAL_MODE_SEL(x) ( (x&0x1)<<28) ++#define s_RGA_ALPHA_CON_DITHER_ENABLE(x) ( (x&0x1)<<29) ++#define s_RGA_ALPHA_CON_GRADIENT_CAL_MODE(x) ( (x&0x1)<<30) ++#define s_RGA_ALPHA_CON_AA_SEL(x) ( (x&0x1)<<31) ++ ++ ++/* blur sharp mode */ ++#define m_RGA_BLUR_SHARP_FILTER_MODE ( 0x1<<25 ) ++#define m_RGA_BLUR_SHARP_FILTER_TYPE ( 0x3<<26 ) ++ ++#define s_RGA_BLUR_SHARP_FILTER_MODE(x) ( (x&0x1)<<25 ) ++#define s_RGA_BLUR_SHARP_FILTER_TYPE(x) ( (x&0x3)<<26 ) ++ ++ ++/* pre scale mode */ ++#define m_RGA_PRE_SCALE_HOR_RATIO ( 0x3 <<20 ) ++#define m_RGA_PRE_SCALE_VER_RATIO ( 0x3 <<22 ) ++#define m_RGA_PRE_SCALE_OUTPUT_FORMAT ( 0x1 <<24 ) ++ ++#define s_RGA_PRE_SCALE_HOR_RATIO(x) ( (x&0x3) <<20 ) ++#define s_RGA_PRE_SCALE_VER_RATIO(x) ( (x&0x3) <<22 ) ++#define s_RGA_PRE_SCALE_OUTPUT_FORMAT(x) ( (x&0x1) <<24 ) ++ ++ ++ ++/* RGA_MMU_CTRL*/ ++#define m_RGA_MMU_CTRL_TLB_ADDR ( 0xffffffff<<0) ++#define m_RGA_MMU_CTRL_PAGE_TABLE_SIZE ( 0x3<<4 ) ++#define m_RGA_MMU_CTRL_MMU_ENABLE ( 0x1<<0 ) ++#define m_RGA_MMU_CTRL_SRC_FLUSH ( 0x1<<1 ) ++#define m_RGA_MMU_CTRL_DST_FLUSH ( 0x1<<2 ) ++#define m_RGA_MMU_CTRL_CMD_CHAN_FLUSH ( 0x1<<3 ) ++ ++#define s_RGA_MMU_CTRL_TLB_ADDR(x) ((x&0xffffffff)) ++#define s_RGA_MMU_CTRL_PAGE_TABLE_SIZE(x) ((x&0x3)<<4) ++#define s_RGA_MMU_CTRL_MMU_ENABLE(x) ((x&0x1)<<0) ++#define s_RGA_MMU_CTRL_SRC_FLUSH(x) ((x&0x1)<<1) ++#define s_RGA_MMU_CTRL_DST_FLUSH(x) ((x&0x1)<<2) ++#define s_RGA_MMU_CTRL_CMD_CHAN_FLUSH(x) ((x&0x1)<<3) ++ ++#endif ++ ++/* ++#define RGA_MODE_CTRL_OFFSET 0x0 ++#define RGA_SRC_Y_MST_OFFSET 0x4 ++#define RGA_SRC_CB_MST_OFFSET 0x8 ++#define RGA_SRC_CR_MST_OFFSET 0xc ++#define RGA_SRC_VIR_INFO_OFFSET 0x10 ++#define RGA_SRC_ACT_INFO_OFFSET 0x14 ++#define RGA_SRC_X_PARA_OFFSET 0x18 ++#define RGA_SRC_Y_PARA_OFFSET 0x1c ++#define RGA_SRC_TILE_XINFO_OFFSET 0x20 ++#define RGA_SRC_TILE_YINFO_OFFSET 0x24 ++#define RGA_SRC_TILE_H_INCR_OFFSET 0x28 ++#define RGA_SRC_TILE_V_INCR_OFFSET 0x2c ++#define RGA_SRC_TILE_OFFSETX_OFFSET 0x30 ++#define RGA_SRC_TILE_OFFSETY_OFFSET 0x34 ++#define RGA_SRC_BG_COLOR_OFFSET 0x38 ++ ++#define RGA_SRC_FG_COLOR_OFFSET 0x3c ++#define RGA_LINE_DRAWING_COLOR_OFFSET 0x3c ++ ++#define RGA_SRC_TR_COLOR0_OFFSET 0x40 ++#define RGA_CP_GR_A_OFFSET 0x40 //repeat ++ ++#define RGA_SRC_TR_COLOR1_OFFSET 0x44 ++#define RGA_CP_GR_B_OFFSET 0x44 //repeat ++ ++#define RGA_LINE_DRAW_OFFSET 0x48 ++#define RGA_PAT_START_POINT_OFFSET 0x48 //repeat ++ ++#define RGA_DST_MST_OFFSET 0x4c ++#define RGA_LUT_MST_OFFSET 0x4c //repeat ++#define RGA_PAT_MST_OFFSET 0x4c //repeat ++#define RGA_LINE_DRAWING_MST_OFFSET 0x4c //repeat ++ ++#define RGA_DST_VIR_INFO_OFFSET 0x50 ++ ++#define RGA_DST_CTR_INFO_OFFSET 0x54 ++#define RGA_LINE_DRAW_XY_INFO_OFFSET 0x54 //repeat ++ ++#define RGA_ALPHA_CON_OFFSET 0x58 ++#define RGA_FADING_CON_OFFSET 0x5c ++ ++#define RGA_PAT_CON_OFFSET 0x60 ++#define RGA_LINE_DRAWING_WIDTH_OFFSET 0x60 //repeat ++ ++#define RGA_ROP_CON0_OFFSET 0x64 ++#define RGA_CP_GR_G_OFFSET 0x64 //repeat ++#define RGA_PRESCL_CB_MST_OFFSET 0x64 //repeat ++ ++#define RGA_ROP_CON1_OFFSET 0x68 ++#define RGA_CP_GR_R_OFFSET 0x68 //repeat ++#define RGA_PRESCL_CR_MST_OFFSET 0x68 //repeat ++ ++#define RGA_MMU_CTRL_OFFSET 0x6c ++ ++ ++#define RGA_SYS_CTRL_OFFSET 0x000 ++#define RGA_CMD_CTRL_OFFSET 0x004 ++#define RGA_CMD_ADDR_OFFSET 0x008 ++#define RGA_STATUS_OFFSET 0x00c ++#define RGA_INT_OFFSET 0x010 ++#define RGA_AXI_ID_OFFSET 0x014 ++#define RGA_MMU_STA_CTRL_OFFSET 0x018 ++#define RGA_MMU_STA_OFFSET 0x01c ++*/ ++//hxx ++ ++#define RGA_SYS_CTRL_OFFSET (RGA_SYS_CTRL-0x100) ++#define RGA_CMD_CTRL_OFFSET (RGA_CMD_CTRL-0x100) ++#define RGA_CMD_ADDR_OFFSET (RGA_CMD_ADDR-0x100) ++#define RGA_STATUS_OFFSET (RGA_STATUS-0x100) ++#define RGA_INT_OFFSET (RGA_INT-0x100) ++#define RGA_AXI_ID_OFFSET (RGA_AXI_ID-0x100) ++#define RGA_MMU_STA_CTRL_OFFSET (RGA_MMU_STA_CTRL-0x100) ++#define RGA_MMU_STA_OFFSET (RGA_MMU_STA-0x100) ++ ++#define RGA_MODE_CTRL_OFFSET (RGA_MODE_CTRL-0x100) ++#define RGA_SRC_Y_MST_OFFSET (RGA_SRC_Y_MST-0x100) ++#define RGA_SRC_CB_MST_OFFSET (RGA_SRC_CB_MST-0x100) ++#define RGA_SRC_CR_MST_OFFSET (RGA_SRC_CR_MST-0x100) ++#define RGA_SRC_VIR_INFO_OFFSET (RGA_SRC_VIR_INFO-0x100) ++#define RGA_SRC_ACT_INFO_OFFSET (RGA_SRC_ACT_INFO-0x100) ++#define RGA_SRC_X_PARA_OFFSET (RGA_SRC_X_PARA-0x100) ++#define RGA_SRC_Y_PARA_OFFSET (RGA_SRC_Y_PARA-0x100) ++#define RGA_SRC_TILE_XINFO_OFFSET (RGA_SRC_TILE_XINFO-0x100) ++#define RGA_SRC_TILE_YINFO_OFFSET (RGA_SRC_TILE_YINFO-0x100) ++#define RGA_SRC_TILE_H_INCR_OFFSET (RGA_SRC_TILE_H_INCR-0x100) ++#define RGA_SRC_TILE_V_INCR_OFFSET (RGA_SRC_TILE_V_INCR-0x100) ++#define RGA_SRC_TILE_OFFSETX_OFFSET (RGA_SRC_TILE_OFFSETX-0x100) ++#define RGA_SRC_TILE_OFFSETY_OFFSET (RGA_SRC_TILE_OFFSETY-0x100) ++#define RGA_SRC_BG_COLOR_OFFSET (RGA_SRC_BG_COLOR-0x100) ++ ++#define RGA_SRC_FG_COLOR_OFFSET (RGA_SRC_FG_COLOR-0x100) ++#define RGA_LINE_DRAWING_COLOR_OFFSET (RGA_LINE_DRAWING_COLOR-0x100) ++ ++#define RGA_SRC_TR_COLOR0_OFFSET (RGA_SRC_TR_COLOR0-0x100) ++#define RGA_CP_GR_A_OFFSET (RGA_CP_GR_A-0x100) //repeat ++ ++#define RGA_SRC_TR_COLOR1_OFFSET (RGA_SRC_TR_COLOR1-0x100) ++#define RGA_CP_GR_B_OFFSET (RGA_CP_GR_B-0x100) //repeat ++ ++#define RGA_LINE_DRAW_OFFSET (RGA_LINE_DRAW-0x100) ++#define RGA_PAT_START_POINT_OFFSET (RGA_PAT_START_POINT-0x100) //repeat ++ ++#define RGA_DST_MST_OFFSET (RGA_DST_MST-0x100) ++#define RGA_LUT_MST_OFFSET (RGA_LUT_MST-0x100) //repeat ++#define RGA_PAT_MST_OFFSET (RGA_PAT_MST-0x100) //repeat ++#define RGA_LINE_DRAWING_MST_OFFSET (RGA_LINE_DRAWING_MST-0x100) //repeat ++ ++#define RGA_DST_VIR_INFO_OFFSET (RGA_DST_VIR_INFO-0x100) ++ ++#define RGA_DST_CTR_INFO_OFFSET (RGA_DST_CTR_INFO-0x100) ++#define RGA_LINE_DRAW_XY_INFO_OFFSET (RGA_LINE_DRAW_XY_INFO-0x100) //repeat ++ ++#define RGA_ALPHA_CON_OFFSET (RGA_ALPHA_CON-0x100) ++ ++#define RGA_PAT_CON_OFFSET (RGA_PAT_CON-0x100) ++#define RGA_LINE_DRAWING_WIDTH_OFFSET (RGA_DST_VIR_WIDTH_PIX-0x100) //repeat ++ ++#define RGA_ROP_CON0_OFFSET (RGA_ROP_CON0-0x100) ++#define RGA_CP_GR_G_OFFSET (RGA_CP_GR_G-0x100) //repeat ++#define RGA_PRESCL_CB_MST_OFFSET (RGA_PRESCL_CB_MST-0x100) //repeat ++ ++#define RGA_ROP_CON1_OFFSET (RGA_ROP_CON1-0x100) ++#define RGA_CP_GR_R_OFFSET (RGA_CP_GR_R-0x100) //repeat ++#define RGA_PRESCL_CR_MST_OFFSET (RGA_PRESCL_CR_MST-0x100) //repeat ++ ++#define RGA_FADING_CON_OFFSET (RGA_FADING_CON-0x100) ++#define RGA_MMU_TLB_OFFSET (RGA_MMU_TBL-0x100) ++ ++#define RGA_YUV_OUT_CFG_OFFSET (RGA_YUV_OUT_CFG-0x100) ++#define RGA_DST_UV_MST_OFFSET (RGA_DST_UV_MST-0x100) ++ ++ ++ ++void matrix_cal(const struct rga_req *msg, TILE_INFO *tile); ++ ++ ++int RGA_gen_reg_info(const struct rga_req *msg, unsigned char *base); ++uint8_t RGA_pixel_width_init(uint32_t format); ++ diff --git a/drivers/video/rockchip/rga/rga_rop.h b/drivers/video/rockchip/rga/rga_rop.h new file mode 100644 index 000000000..ed9758711 @@ -1845800,61 +1845800,61 @@ index 000000000..ed9758711 +++ b/drivers/video/rockchip/rga/rga_rop.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __RGA_ROP_H__ -+#define __RGA_ROP_H__ -+ -+unsigned int ROP3_code[256] = -+{ -+ 0x00000007, 0x00000451, 0x00006051, 0x00800051, 0x00007041, 0x00800041, 0x00804830, 0x000004f0,//0 -+ 0x00800765, 0x000004b0, 0x00000065, 0x000004f4, 0x00000075, 0x000004e6, 0x00804850, 0x00800005, -+ -+ 0x00006850, 0x00800050, 0x00805028, 0x00000568, 0x00804031, 0x00000471, 0x002b6071, 0x018037aa,//1 -+ 0x008007aa, 0x00036071, 0x00002c6a, 0x00803631, 0x00002d68, 0x00802721, 0x008002d0, 0x000006d0, -+ -+ 0x0080066e, 0x00000528, 0x00000066, 0x0000056c, 0x018007aa, 0x0002e06a, 0x00003471, 0x00834031,//2 -+ 0x00800631, 0x0002b471, 0x00006071, 0x008037aa, 0x000036d0, 0x008002d4, 0x00002d28, 0x000006d4, -+ -+ 0x0000006e, 0x00000565, 0x00003451, 0x00800006, 0x000034f0, 0x00834830, 0x00800348, 0x00000748,//3 -+ 0x00002f48, 0x0080034c, 0x000034b0, 0x0000074c, 0x00000031, 0x00834850, 0x000034e6, 0x00800071, -+ -+ 0x008006f4, 0x00000431, 0x018007a1, 0x00b6e870, 0x00000074, 0x0000046e, 0x00002561, 0x00802f28,//4 -+ 0x00800728, 0x0002a561, 0x000026c2, 0x008002c6, 0x00007068, 0x018035aa, 0x00002c2a, 0x000006c6, -+ -+ 0x0000006c, 0x00000475, 0x000024e2, 0x008036b0, 0x00804051, 0x00800004, 0x00800251, 0x00000651, -+ 0x00002e4a, 0x0080024e, 0x00000028, 0x00824842, 0x000024a2, 0x0000064e, 0x000024f4, 0x00800068,//5 -+ -+ 0x008006b0, 0x000234f0, 0x00002741, 0x00800345, 0x00003651, 0x00800255, 0x00000030, 0x00834051, -+ 0x00a34842, 0x000002b0, 0x00800271, 0x0002b651, 0x00800368, 0x0002a741, 0x0000364e, 0x00806830,//6 -+ -+ 0x00006870, 0x008037a2, 0x00003431, 0x00000745, 0x00002521, 0x00000655, 0x0000346e, 0x00800062, -+ 0x008002f0, 0x000236d0, 0x000026d4, 0x00807028, 0x000036c6, 0x00806031, 0x008005aa, 0x00000671,//7 -+ -+ 0x00800671, 0x000005aa, 0x00006031, 0x008036c6, 0x00007028, 0x00802e55, 0x008236d0, 0x000002f0, -+ 0x00000070, 0x0080346e, 0x00800655, 0x00802521, 0x00800745, 0x00803431, 0x000037a2, 0x00806870,//8 -+ -+ 0x00006830, 0x0080364e, 0x00822f48, 0x00000361, 0x0082b651, 0x00000271, 0x00800231, 0x002b4051, -+ 0x00034051, 0x00800030, 0x0080026e, 0x00803651, 0x0080036c, 0x00802741, 0x008234f0, 0x000006b0,//9 -+ -+ 0x00000068, 0x00802c75, 0x0080064e, 0x008024a2, 0x0002c04a, 0x00800021, 0x00800275, 0x00802e51, -+ 0x00800651, 0x00000251, 0x00800000, 0x00004051, 0x000036b0, 0x008024e2, 0x00800475, 0x00000045,//a -+ -+ 0x008006c6, 0x00802c2a, 0x000035aa, 0x00807068, 0x008002f4, 0x008026c2, 0x00822d68, 0x00000728, -+ 0x00002f28, 0x00802561, 0x0080046e, 0x00000046, 0x00836870, 0x000007a2, 0x00800431, 0x00004071,//b -+ -+ 0x00000071, 0x008034e6, 0x00034850, 0x00800031, 0x0080074c, 0x008034b0, 0x00800365, 0x00802f48, -+ 0x00800748, 0x00000341, 0x000026a2, 0x008034f0, 0x00800002, 0x00005048, 0x00800565, 0x00000055,//c -+ -+ 0x008006d4, 0x00802d28, 0x008002e6, 0x008036d0, 0x000037aa, 0x00806071, 0x0082b471, 0x00000631, -+ 0x00002e2a, 0x00803471, 0x00826862, 0x010007aa, 0x0080056c, 0x00000054, 0x00800528, 0x00005068,//d -+ -+ 0x008006d0, 0x000002d0, 0x00002721, 0x00802d68, 0x00003631, 0x00802c6a, 0x00836071, 0x000007aa, -+ 0x010037aa, 0x00a36870, 0x00800471, 0x00004031, 0x00800568, 0x00005028, 0x00000050, 0x00800545,//e -+ -+ 0x00800001, 0x00004850, 0x008004e6, 0x0000004e, 0x008004f4, 0x0000004c, 0x008004b0, 0x00004870, -+ 0x008004f0, 0x00004830, 0x00000048, 0x0080044e, 0x00000051, 0x008004d4, 0x00800451, 0x00800007,//f -+}; -+ -+#endif ++#ifndef __RGA_ROP_H__ ++#define __RGA_ROP_H__ ++ ++unsigned int ROP3_code[256] = ++{ ++ 0x00000007, 0x00000451, 0x00006051, 0x00800051, 0x00007041, 0x00800041, 0x00804830, 0x000004f0,//0 ++ 0x00800765, 0x000004b0, 0x00000065, 0x000004f4, 0x00000075, 0x000004e6, 0x00804850, 0x00800005, ++ ++ 0x00006850, 0x00800050, 0x00805028, 0x00000568, 0x00804031, 0x00000471, 0x002b6071, 0x018037aa,//1 ++ 0x008007aa, 0x00036071, 0x00002c6a, 0x00803631, 0x00002d68, 0x00802721, 0x008002d0, 0x000006d0, ++ ++ 0x0080066e, 0x00000528, 0x00000066, 0x0000056c, 0x018007aa, 0x0002e06a, 0x00003471, 0x00834031,//2 ++ 0x00800631, 0x0002b471, 0x00006071, 0x008037aa, 0x000036d0, 0x008002d4, 0x00002d28, 0x000006d4, ++ ++ 0x0000006e, 0x00000565, 0x00003451, 0x00800006, 0x000034f0, 0x00834830, 0x00800348, 0x00000748,//3 ++ 0x00002f48, 0x0080034c, 0x000034b0, 0x0000074c, 0x00000031, 0x00834850, 0x000034e6, 0x00800071, ++ ++ 0x008006f4, 0x00000431, 0x018007a1, 0x00b6e870, 0x00000074, 0x0000046e, 0x00002561, 0x00802f28,//4 ++ 0x00800728, 0x0002a561, 0x000026c2, 0x008002c6, 0x00007068, 0x018035aa, 0x00002c2a, 0x000006c6, ++ ++ 0x0000006c, 0x00000475, 0x000024e2, 0x008036b0, 0x00804051, 0x00800004, 0x00800251, 0x00000651, ++ 0x00002e4a, 0x0080024e, 0x00000028, 0x00824842, 0x000024a2, 0x0000064e, 0x000024f4, 0x00800068,//5 ++ ++ 0x008006b0, 0x000234f0, 0x00002741, 0x00800345, 0x00003651, 0x00800255, 0x00000030, 0x00834051, ++ 0x00a34842, 0x000002b0, 0x00800271, 0x0002b651, 0x00800368, 0x0002a741, 0x0000364e, 0x00806830,//6 ++ ++ 0x00006870, 0x008037a2, 0x00003431, 0x00000745, 0x00002521, 0x00000655, 0x0000346e, 0x00800062, ++ 0x008002f0, 0x000236d0, 0x000026d4, 0x00807028, 0x000036c6, 0x00806031, 0x008005aa, 0x00000671,//7 ++ ++ 0x00800671, 0x000005aa, 0x00006031, 0x008036c6, 0x00007028, 0x00802e55, 0x008236d0, 0x000002f0, ++ 0x00000070, 0x0080346e, 0x00800655, 0x00802521, 0x00800745, 0x00803431, 0x000037a2, 0x00806870,//8 ++ ++ 0x00006830, 0x0080364e, 0x00822f48, 0x00000361, 0x0082b651, 0x00000271, 0x00800231, 0x002b4051, ++ 0x00034051, 0x00800030, 0x0080026e, 0x00803651, 0x0080036c, 0x00802741, 0x008234f0, 0x000006b0,//9 ++ ++ 0x00000068, 0x00802c75, 0x0080064e, 0x008024a2, 0x0002c04a, 0x00800021, 0x00800275, 0x00802e51, ++ 0x00800651, 0x00000251, 0x00800000, 0x00004051, 0x000036b0, 0x008024e2, 0x00800475, 0x00000045,//a ++ ++ 0x008006c6, 0x00802c2a, 0x000035aa, 0x00807068, 0x008002f4, 0x008026c2, 0x00822d68, 0x00000728, ++ 0x00002f28, 0x00802561, 0x0080046e, 0x00000046, 0x00836870, 0x000007a2, 0x00800431, 0x00004071,//b ++ ++ 0x00000071, 0x008034e6, 0x00034850, 0x00800031, 0x0080074c, 0x008034b0, 0x00800365, 0x00802f48, ++ 0x00800748, 0x00000341, 0x000026a2, 0x008034f0, 0x00800002, 0x00005048, 0x00800565, 0x00000055,//c ++ ++ 0x008006d4, 0x00802d28, 0x008002e6, 0x008036d0, 0x000037aa, 0x00806071, 0x0082b471, 0x00000631, ++ 0x00002e2a, 0x00803471, 0x00826862, 0x010007aa, 0x0080056c, 0x00000054, 0x00800528, 0x00005068,//d ++ ++ 0x008006d0, 0x000002d0, 0x00002721, 0x00802d68, 0x00003631, 0x00802c6a, 0x00836071, 0x000007aa, ++ 0x010037aa, 0x00a36870, 0x00800471, 0x00004031, 0x00800568, 0x00005028, 0x00000050, 0x00800545,//e ++ ++ 0x00800001, 0x00004850, 0x008004e6, 0x0000004e, 0x008004f4, 0x0000004c, 0x008004b0, 0x00004870, ++ 0x008004f0, 0x00004830, 0x00000048, 0x0080044e, 0x00000051, 0x008004d4, 0x00800451, 0x00800007,//f ++}; ++ ++#endif diff --git a/drivers/video/rockchip/rga/rga_type.h b/drivers/video/rockchip/rga/rga_type.h new file mode 100644 index 000000000..ce3610ab9 @@ -1845862,54 +1845862,54 @@ index 000000000..ce3610ab9 +++ b/drivers/video/rockchip/rga/rga_type.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ -+#ifndef __RGA_TYPE_H__ -+#define __RGA_TYPE_H__ -+ -+ -+#ifdef __cplusplus -+#if __cplusplus -+} -+#endif -+#endif /* __cplusplus */ -+ -+typedef unsigned int UWORD32; -+typedef unsigned int uint32; -+typedef unsigned int RK_U32; -+ -+typedef unsigned short UWORD16; -+typedef unsigned short RK_U16; -+ -+typedef unsigned char UBYTE; -+typedef unsigned char RK_U8; -+ -+typedef int WORD32; -+typedef int RK_S32; -+ -+typedef short WORD16; -+typedef short RK_S16; -+ -+typedef char BYTE; -+typedef char RK_S8; -+ -+ -+#ifndef NULL -+#define NULL 0L -+#endif -+ -+#ifndef TRUE -+#define TRUE 1L -+#endif -+ -+ -+#ifdef __cplusplus -+#if __cplusplus -+} -+#endif -+#endif /* __cplusplus */ -+ -+ -+#endif /* __RGA_TYPR_H__ */ -+ ++#ifndef __RGA_TYPE_H__ ++#define __RGA_TYPE_H__ ++ ++ ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif ++#endif /* __cplusplus */ ++ ++typedef unsigned int UWORD32; ++typedef unsigned int uint32; ++typedef unsigned int RK_U32; ++ ++typedef unsigned short UWORD16; ++typedef unsigned short RK_U16; ++ ++typedef unsigned char UBYTE; ++typedef unsigned char RK_U8; ++ ++typedef int WORD32; ++typedef int RK_S32; ++ ++typedef short WORD16; ++typedef short RK_S16; ++ ++typedef char BYTE; ++typedef char RK_S8; ++ ++ ++#ifndef NULL ++#define NULL 0L ++#endif ++ ++#ifndef TRUE ++#define TRUE 1L ++#endif ++ ++ ++#ifdef __cplusplus ++#if __cplusplus ++} ++#endif ++#endif /* __cplusplus */ ++ ++ ++#endif /* __RGA_TYPR_H__ */ ++ diff --git a/drivers/video/rockchip/rga2/Kconfig b/drivers/video/rockchip/rga2/Kconfig new file mode 100644 index 000000000..49a0f62b9 @@ -1909216,35 +1909216,35 @@ index 000000000..899a583fd --- /dev/null +++ b/include/trace/events/platform_trace_event.h @@ -0,0 +1,30 @@ -+/* SPDX-License-Identifier: GPL-2.0-or-later */ -+#undef TRACE_SYSTEM -+#define TRACE_SYSTEM platform_trace_event -+ -+#if !defined(_TRACE_PLATFORM_TRACE_EVENT_H) || defined(TRACE_HEADER_MULTI_READ) -+#define _TRACE_PLATFORM_TRACE_EVENT_H -+ -+#include -+ -+TRACE_EVENT(platfrom_trace_record_messages, -+ TP_PROTO( -+ const char *buf -+ ), -+ -+ TP_ARGS(buf), -+ -+ TP_STRUCT__entry( -+ __string(msg, buf) -+ ), -+ -+ TP_fast_assign( -+ __assign_str(msg, buf) -+ ), -+ -+ TP_printk("platform trace info msg='%s'", __get_str(msg)) -+); -+#endif /* _TRACE_PLATFORM_TRACE_EVENT_H */ -+ -+/* This part must be outside protection */ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++#undef TRACE_SYSTEM ++#define TRACE_SYSTEM platform_trace_event ++ ++#if !defined(_TRACE_PLATFORM_TRACE_EVENT_H) || defined(TRACE_HEADER_MULTI_READ) ++#define _TRACE_PLATFORM_TRACE_EVENT_H ++ ++#include ++ ++TRACE_EVENT(platfrom_trace_record_messages, ++ TP_PROTO( ++ const char *buf ++ ), ++ ++ TP_ARGS(buf), ++ ++ TP_STRUCT__entry( ++ __string(msg, buf) ++ ), ++ ++ TP_fast_assign( ++ __assign_str(msg, buf) ++ ), ++ ++ TP_printk("platform trace info msg='%s'", __get_str(msg)) ++); ++#endif /* _TRACE_PLATFORM_TRACE_EVENT_H */ ++ ++/* This part must be outside protection */ +#include \ No newline at end of file diff --git a/include/trace/events/sync.h b/include/trace/events/sync.h -- Gitee