linux-kernel-4.4 移植 (2)解决上部遗留DMA-PL330的问题

时间:2022-04-29 08:48:42

查看drivers/tty/serial/samsung.c文件发现,当传输数据量小于ourport->min_dma_size时,不使用DMA,大于等于min_mda_size时才是使用DMA,因此可以判断时DMA的问题。

static void s3c24xx_serial_start_next_tx(struct s3c24xx_uart_port *ourport)
{
    struct uart_port *port = &ourport->port;
    struct circ_buf *xmit = &port->state->xmit;
    unsigned long count;

    /* Get data size up to the end of buffer */
    count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);                                                                     

    if (!count) {
        s3c24xx_serial_stop_tx(port);
        return;
    }

    if (!ourport->dma || !ourport->dma->tx_chan ||
        count < ourport->min_dma_size ||
        xmit->tail & (dma_get_cache_alignment() - 1))
        s3c24xx_serial_start_tx_pio(ourport);
    else
        s3c24xx_serial_start_tx_dma(ourport, count);
}

 

解决方法


查阅资料发现【为了强制执行对非安全世界外设和地址访问的限制,Exynos4412配备了“TrustZone保护控制器”和“TrustZone地址空间控制器”。它们控制是否只有安全世界可访问任何给定的外设或者内存地址或安全和非安全世界。另一个需要注意的重要事项,即使CPU在安全模式下运行,PL330 DMA控制器也始终使用非安全模式,因此,如果尝试使用DMA访问在TZPC中设置为“仅安全”的内容,则会出现故障并且DMA传输将失败。所需要的只是将所有内存标记为非安全可读写,并将所有外设标记为非安全可读写即可。】
具体如下:

diff --git a/arch/arm/mach-exynos/dmc_init_exynos4412.c b/arch/arm/mach-exynos/d
index 2b2bc3b..1f756f8 100644
--- a/arch/arm/mach-exynos/dmc_init_exynos4412.c
+++ b/arch/arm/mach-exynos/dmc_init_exynos4412.c
@@ -31,6 +31,24 @@
 #include "common_setup.h"
 #include "exynos4412_setup.h"
 
+#define NR_TZASC_BANKS  4
++/* Allow non-secure and secure access to all memory */+#define RA0_VAL 0xf0000000
++static void tzasc_init (void)  {+    unsigned int start = samsung_get_base_dmc_tzasc();++    unsigned int end = start + (DMC_OFFSET * (NR_TZASC_BANKS - 1));+    for(;start <= end; start += DMC_OFFSET) {+        struct exynos4412_tzasc *asc = (struct exynos4412_tzasc *)start;+        writel(RA0_VAL, &asc -> region_attributes_0);+    }+}
 #ifdef TINY4412
 struct mem_timings mem = {
    .direct_cmd_msr = {
@@ -250,4 +268,8 @@ void mem_ctrl_init(int reset)
    dmc = (struct exynos4_dmc *)(samsung_get_base_dmc_ctrl()
                 +DMC_OFFSET);
    dmc_init(dmc);
++   tzasc_init();++
 }
diff --git a/arch/arm/mach-exynos/include/mach/cpu.h b/arch/arm/mach-exynos/incl
index 1f722df..5800a18 100644
--- a/arch/arm/mach-exynos/include/mach/cpu.h
+++ b/arch/arm/mach-exynos/include/mach/cpu.h
@@ -68,6 +68,9 @@
 #define EXYNOS4X12_SYSTIMER_BASE       0x10050000
 #define EXYNOS4X12_WATCHDOG_BASE       0x10060000
 #define EXYNOS4X12_TZPC_BASE           0x10110000
+
+#define EXYNOS4X12_DMC_TZASC_BASE              0x10700000
+
 #define EXYNOS4X12_DMC_CTRL_BASE       0x10600000
 #define EXYNOS4X12_GPIO_PART4_BASE     0x106E0000
 #define EXYNOS4X12_ACE_SFR_BASE                0x10830000
@@ -101,7 +104,8 @@
 #define EXYNOS4X12_AUDIOSS_BASE                DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_USB_HOST_XHCI_BASE  DEVICE_NOT_AVAILABLE
 #define EXYNOS4X12_USB3PHY_BASE                DEVICE_NOT_AVAILABLE
-#define EXYNOS4X12_DMC_TZASC_BASE      DEVICE_NOT_AVAILABLE
+
+/* #define EXYNOS4X12_DMC_TZASC_BASE   DEVICE_NOT_AVAILABLE */
 
 /* EXYNOS5 */
 #define EXYNOS5_I2C_SPACING            0x10000
diff --git a/arch/arm/mach-exynos/include/mach/dmc.h b/arch/arm/mach-exynos/incl
index 4990a1a..304e094 100644
--- a/arch/arm/mach-exynos/include/mach/dmc.h
+++ b/arch/arm/mach-exynos/include/mach/dmc.h
@@ -419,6 +419,30 @@ struct exynos5420_phy_control {
        unsigned int phy_con42;
 };
 
+struct exynos4412_tzasc {
+    unsigned char res1[0x100];
+    unsigned int  region_setup_low_0; //100
+    unsigned int  region_setup_high_0; //104
+    unsigned int  region_attributes_0; //108
+
+    unsigned char res2;//10c
+    unsigned int  region_setup_low_1; //110
+    unsigned int  region_setup_high_1; //114
+    unsigned int  region_attributes_1; //118
+    
+    unsigned char res3;
+    unsigned int  region_setup_low_2; //120
+    unsigned int  region_setup_high_2; //124
+    unsigned int  region_attributes_2; //128
+    
+    unsigned char res4;
+    unsigned int  region_setup_low_3; //130
+    unsigned int  region_setup_high_3; //134
+    unsigned int  region_attributes_3; //138
+ 
+};
+
+
 struct exynos5420_tzasc {
        unsigned char res1[0xf00];
        unsigned int membaseconfig0;
diff --git a/arch/arm/mach-exynos/lowlevel_init.c b/arch/arm/mach-exynos/lowleve
index de85643..4736d60 100644
--- a/arch/arm/mach-exynos/lowlevel_init.c
+++ b/arch/arm/mach-exynos/lowlevel_init.c
@@ -229,10 +229,7 @@ int do_lowlevel_init(void)
 #endif
 #endif
                mem_ctrl_init(actions & DO_MEM_RESET);
-
-#ifndef  TINY4412 
       tzpc_init();
-#endif
        }
 
        return actions & DO_WAKEUP;
diff --git a/sd_fuse/tiny4412/sd_fusing.sh b/sd_fuse/tiny4412/sd_fusing.sh
index 2658c53..956fa29 100755
--- a/sd_fuse/tiny4412/sd_fusing.sh
+++ b/sd_fuse/tiny4412/sd_fusing.sh
@@ -63,12 +63,12 @@ fi
 signed_bl1_position=1
 bl2_position=17
 uboot_position=81
-tzsw_position=705
+tzsw_position=1105
 
 
 #<TrustZone S/W fusing>
-#echo "---------------------------------------"
-#echo "TrustZone S/W fusing"
-#dd iflag=dsync oflag=dsync if=./E4412_tzsw.bin of=$1 seek=$tzsw_position
+echo "---------------------------------------"
+echo "TrustZone S/W fusing"
+dd iflag=dsync oflag=dsync if=./E4412_tzsw.bin of=$1 seek=$tzsw_position
 
 #<flush to disk>
 sync

 

参考:https://blog.csdn.net/qq_25370227/article/details/84891632