@@ -182,14 +182,8 @@ static bool arm_v7s_is_mtk_enabled(struct io_pgtable_cfg *cfg)
182182 (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT );
183183}
184184
185- static arm_v7s_iopte paddr_to_iopte (phys_addr_t paddr , int lvl ,
186- struct io_pgtable_cfg * cfg )
185+ static arm_v7s_iopte to_mtk_iopte (phys_addr_t paddr , arm_v7s_iopte pte )
187186{
188- arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK (lvl );
189-
190- if (!arm_v7s_is_mtk_enabled (cfg ))
191- return pte ;
192-
193187 if (paddr & BIT_ULL (32 ))
194188 pte |= ARM_V7S_ATTR_MTK_PA_BIT32 ;
195189 if (paddr & BIT_ULL (33 ))
@@ -199,6 +193,17 @@ static arm_v7s_iopte paddr_to_iopte(phys_addr_t paddr, int lvl,
199193 return pte ;
200194}
201195
196+ static arm_v7s_iopte paddr_to_iopte (phys_addr_t paddr , int lvl ,
197+ struct io_pgtable_cfg * cfg )
198+ {
199+ arm_v7s_iopte pte = paddr & ARM_V7S_LVL_MASK (lvl );
200+
201+ if (arm_v7s_is_mtk_enabled (cfg ))
202+ return to_mtk_iopte (paddr , pte );
203+
204+ return pte ;
205+ }
206+
202207static phys_addr_t iopte_to_paddr (arm_v7s_iopte pte , int lvl ,
203208 struct io_pgtable_cfg * cfg )
204209{
@@ -240,18 +245,26 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp,
240245 dma_addr_t dma ;
241246 size_t size = ARM_V7S_TABLE_SIZE (lvl , cfg );
242247 void * table = NULL ;
248+ gfp_t gfp_l1 ;
249+
250+ /*
251+ * ARM_MTK_TTBR_EXT extend the translation table base support larger
252+ * memory address.
253+ */
254+ gfp_l1 = cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ?
255+ GFP_KERNEL : ARM_V7S_TABLE_GFP_DMA ;
243256
244257 if (lvl == 1 )
245- table = (void * )__get_free_pages (
246- __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA , get_order (size ));
258+ table = (void * )__get_free_pages (gfp_l1 | __GFP_ZERO , get_order (size ));
247259 else if (lvl == 2 )
248260 table = kmem_cache_zalloc (data -> l2_tables , gfp );
249261
250262 if (!table )
251263 return NULL ;
252264
253265 phys = virt_to_phys (table );
254- if (phys != (arm_v7s_iopte )phys ) {
266+ if (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ?
267+ phys >= (1ULL << cfg -> oas ) : phys != (arm_v7s_iopte )phys ) {
255268 /* Doesn't fit in PTE */
256269 dev_err (dev , "Page table does not fit in PTE: %pa" , & phys );
257270 goto out_free ;
@@ -457,9 +470,14 @@ static arm_v7s_iopte arm_v7s_install_table(arm_v7s_iopte *table,
457470 arm_v7s_iopte curr ,
458471 struct io_pgtable_cfg * cfg )
459472{
473+ phys_addr_t phys = virt_to_phys (table );
460474 arm_v7s_iopte old , new ;
461475
462- new = virt_to_phys (table ) | ARM_V7S_PTE_TYPE_TABLE ;
476+ new = phys | ARM_V7S_PTE_TYPE_TABLE ;
477+
478+ if (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT )
479+ new = to_mtk_iopte (phys , new );
480+
463481 if (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_NS )
464482 new |= ARM_V7S_ATTR_NS_TABLE ;
465483
@@ -779,6 +797,8 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
779797 void * cookie )
780798{
781799 struct arm_v7s_io_pgtable * data ;
800+ slab_flags_t slab_flag ;
801+ phys_addr_t paddr ;
782802
783803 if (cfg -> ias > (arm_v7s_is_mtk_enabled (cfg ) ? 34 : ARM_V7S_ADDR_BITS ))
784804 return NULL ;
@@ -788,23 +808,36 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
788808
789809 if (cfg -> quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
790810 IO_PGTABLE_QUIRK_NO_PERMS |
791- IO_PGTABLE_QUIRK_ARM_MTK_EXT ))
811+ IO_PGTABLE_QUIRK_ARM_MTK_EXT |
812+ IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ))
792813 return NULL ;
793814
794815 /* If ARM_MTK_4GB is enabled, the NO_PERMS is also expected. */
795816 if (cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_EXT &&
796817 !(cfg -> quirks & IO_PGTABLE_QUIRK_NO_PERMS ))
797818 return NULL ;
798819
820+ if ((cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ) &&
821+ !arm_v7s_is_mtk_enabled (cfg ))
822+ return NULL ;
823+
799824 data = kmalloc (sizeof (* data ), GFP_KERNEL );
800825 if (!data )
801826 return NULL ;
802827
803828 spin_lock_init (& data -> split_lock );
829+
830+ /*
831+ * ARM_MTK_TTBR_EXT extend the translation table base support larger
832+ * memory address.
833+ */
834+ slab_flag = cfg -> quirks & IO_PGTABLE_QUIRK_ARM_MTK_TTBR_EXT ?
835+ 0 : ARM_V7S_TABLE_SLAB_FLAGS ;
836+
804837 data -> l2_tables = kmem_cache_create ("io-pgtable_armv7s_l2" ,
805838 ARM_V7S_TABLE_SIZE (2 , cfg ),
806839 ARM_V7S_TABLE_SIZE (2 , cfg ),
807- ARM_V7S_TABLE_SLAB_FLAGS , NULL );
840+ slab_flag , NULL );
808841 if (!data -> l2_tables )
809842 goto out_free_data ;
810843
@@ -850,12 +883,16 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
850883 wmb ();
851884
852885 /* TTBR */
853- cfg -> arm_v7s_cfg .ttbr = virt_to_phys (data -> pgd ) | ARM_V7S_TTBR_S |
854- (cfg -> coherent_walk ? (ARM_V7S_TTBR_NOS |
855- ARM_V7S_TTBR_IRGN_ATTR (ARM_V7S_RGN_WBWA ) |
856- ARM_V7S_TTBR_ORGN_ATTR (ARM_V7S_RGN_WBWA )) :
857- (ARM_V7S_TTBR_IRGN_ATTR (ARM_V7S_RGN_NC ) |
858- ARM_V7S_TTBR_ORGN_ATTR (ARM_V7S_RGN_NC )));
886+ paddr = virt_to_phys (data -> pgd );
887+ if (arm_v7s_is_mtk_enabled (cfg ))
888+ cfg -> arm_v7s_cfg .ttbr = paddr | upper_32_bits (paddr );
889+ else
890+ cfg -> arm_v7s_cfg .ttbr = paddr | ARM_V7S_TTBR_S |
891+ (cfg -> coherent_walk ? (ARM_V7S_TTBR_NOS |
892+ ARM_V7S_TTBR_IRGN_ATTR (ARM_V7S_RGN_WBWA ) |
893+ ARM_V7S_TTBR_ORGN_ATTR (ARM_V7S_RGN_WBWA )) :
894+ (ARM_V7S_TTBR_IRGN_ATTR (ARM_V7S_RGN_NC ) |
895+ ARM_V7S_TTBR_ORGN_ATTR (ARM_V7S_RGN_NC )));
859896 return & data -> iop ;
860897
861898out_free_data :
0 commit comments