aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShanker Donthineni <shankerd@codeaurora.org>2017-10-09 12:46:55 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2017-10-13 11:30:58 -0400
commit30ae9610d275f8f03f5bf7612ce71d8af6fc400b (patch)
treea297a65bef8c77e07e010f02bf2e855fccc2b020
parent32bd44dc19de012e22f1fdebd2606b5fb86d54c5 (diff)
irqchip/gic-v3-its: Add missing changes to support 52bit physical address
The current ITS driver works fine as long as normal memory and GICR regions are located within the lower 48bit (>=0 && <2^48) physical address space. Some of the registers GICR_PEND/PROP, GICR_VPEND/VPROP and GITS_CBASER are handled properly but not all when configuring the hardware with 52bit physical address. This patch does the following changes to support 52bit PA. -Handle 52bit PA in GITS_BASERn. -Fix ITT_addr width to 52bits, bits[51:8]. -Fix RDbase width to 52bits, bits[51:16]. -Fix VPT_addr width to 52bits, bits[51:16]. Definition of the GITS_BASERn register when ITS PageSize is 64KB: -Bits[47:16] of the register provide bits[47:16] of the table PA. -Bits[15:12] of the register provide bits[51:48] of the table PA. -Bits[15:00] of the base physical address are 0. Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c26
-rw-r--r--include/linux/irqchip/arm-gic-v3.h2
2 files changed, 23 insertions, 5 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 991cf33750c6..e88395605e32 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -312,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
312 312
313static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) 313static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
314{ 314{
315 its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8); 315 its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
316} 316}
317 317
318static void its_encode_valid(struct its_cmd_block *cmd, int valid) 318static void its_encode_valid(struct its_cmd_block *cmd, int valid)
@@ -322,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
322 322
323static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) 323static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
324{ 324{
325 its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16); 325 its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
326} 326}
327 327
328static void its_encode_collection(struct its_cmd_block *cmd, u16 col) 328static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
@@ -362,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
362 362
363static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) 363static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
364{ 364{
365 its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16); 365 its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
366} 366}
367 367
368static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) 368static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
@@ -1482,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
1482 u64 val = its_read_baser(its, baser); 1482 u64 val = its_read_baser(its, baser);
1483 u64 esz = GITS_BASER_ENTRY_SIZE(val); 1483 u64 esz = GITS_BASER_ENTRY_SIZE(val);
1484 u64 type = GITS_BASER_TYPE(val); 1484 u64 type = GITS_BASER_TYPE(val);
1485 u64 baser_phys, tmp;
1485 u32 alloc_pages; 1486 u32 alloc_pages;
1486 void *base; 1487 void *base;
1487 u64 tmp;
1488 1488
1489retry_alloc_baser: 1489retry_alloc_baser:
1490 alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); 1490 alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
@@ -1500,8 +1500,24 @@ retry_alloc_baser:
1500 if (!base) 1500 if (!base)
1501 return -ENOMEM; 1501 return -ENOMEM;
1502 1502
1503 baser_phys = virt_to_phys(base);
1504
1505 /* Check if the physical address of the memory is above 48bits */
1506 if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
1507
1508 /* 52bit PA is supported only when PageSize=64K */
1509 if (psz != SZ_64K) {
1510 pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
1511 free_pages((unsigned long)base, order);
1512 return -ENXIO;
1513 }
1514
1515 /* Convert 52bit PA to 48bit field */
1516 baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
1517 }
1518
1503retry_baser: 1519retry_baser:
1504 val = (virt_to_phys(base) | 1520 val = (baser_phys |
1505 (type << GITS_BASER_TYPE_SHIFT) | 1521 (type << GITS_BASER_TYPE_SHIFT) |
1506 ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | 1522 ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
1507 ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) | 1523 ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) |
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
index 1ea576c8126f..14b74f22d43c 100644
--- a/include/linux/irqchip/arm-gic-v3.h
+++ b/include/linux/irqchip/arm-gic-v3.h
@@ -372,6 +372,8 @@
372#define GITS_BASER_ENTRY_SIZE_SHIFT (48) 372#define GITS_BASER_ENTRY_SIZE_SHIFT (48)
373#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) 373#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
374#define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) 374#define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48)
375#define GITS_BASER_PHYS_52_to_48(phys) \
376 (((phys) & GENMASK_ULL(47, 16)) | (((phys) >> 48) & 0xf) << 12)
375#define GITS_BASER_SHAREABILITY_SHIFT (10) 377#define GITS_BASER_SHAREABILITY_SHIFT (10)
376#define GITS_BASER_InnerShareable \ 378#define GITS_BASER_InnerShareable \
377 GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) 379 GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)