diff options
author | Shanker Donthineni <shankerd@codeaurora.org> | 2017-10-09 12:46:55 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2017-10-13 11:30:58 -0400 |
commit | 30ae9610d275f8f03f5bf7612ce71d8af6fc400b (patch) | |
tree | a297a65bef8c77e07e010f02bf2e855fccc2b020 | |
parent | 32bd44dc19de012e22f1fdebd2606b5fb86d54c5 (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.c | 26 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic-v3.h | 2 |
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 | ||
313 | static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) | 313 | static 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 | ||
318 | static void its_encode_valid(struct its_cmd_block *cmd, int valid) | 318 | static 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 | ||
323 | static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) | 323 | static 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 | ||
328 | static void its_encode_collection(struct its_cmd_block *cmd, u16 col) | 328 | static 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 | ||
363 | static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) | 363 | static 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 | ||
368 | static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) | 368 | static 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 | ||
1489 | retry_alloc_baser: | 1489 | retry_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 | |||
1503 | retry_baser: | 1519 | retry_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) |