diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2025-09-23 22:59:16 +0200 |
|---|---|---|
| committer | Arnd Bergmann <arnd@arndb.de> | 2025-09-23 22:59:32 +0200 |
| commit | 72af4030bef819e49b9fae1d753a730d517d2abc (patch) | |
| tree | 8ba306a27fbaae2ad5eaebdedd1d04cf6a205a06 /drivers | |
| parent | Merge tag 'qcom-drivers-for-6.18-2' of https://git.kernel.org/pub/scm/linux/k... (diff) | |
| parent | pmdomain: apple: Add "apple,t8103-pmgr-pwrstate" (diff) | |
| download | linux-72af4030bef819e49b9fae1d753a730d517d2abc.tar.gz linux-72af4030bef819e49b9fae1d753a730d517d2abc.zip | |
Merge tag 'apple-soc-drivers-6.18' of https://git.kernel.org/pub/scm/linux/kernel/git/sven/linux into soc/drivers
Apple SoC driver updates for 6.18
Krzysztof Kozlowski asked us to move away from generic compatibles:
- Adjust all dt-bindings to use apple,t8103-XXXX instead of apple,XXXX
as fallback and add a comment that the old generic list should no
longer be extended.
- Add new fallback compatibles to pinctrl, pmdomain, spi, and mca
drivers. These changes have been Acked by their subsystem maintainers
to be merged through our tree together with the dt-bindings.
Support for pre-M1 Apple Silicon:
- SART and mailbox gain support for Apple's A11, which are both
required for NVMe.
- NVMe also gains support for Apple's A11 and the nvme maintainers
prefer that we merge this through the soc tree together with
the mailbox and SART changes.
- SPMI compatibles for A11 and T2 have been added, also going through
the soc tree due to conflicts with the generic compatible removal and
because no driver change is required.
Signed-off-by: Sven Peter <sven@kernel.org>
* tag 'apple-soc-drivers-6.18' of https://git.kernel.org/pub/scm/linux/kernel/git/sven/linux: (32 commits)
pmdomain: apple: Add "apple,t8103-pmgr-pwrstate"
dt-bindings: spmi: Add Apple A11 and T2 compatible
spi: apple: Add "apple,t8103-spi" compatible
ASoC: apple: mca: Add "apple,t8103-mca" compatible
pinctrl: apple: Add "apple,t8103-pinctrl" as compatible
spi: dt-bindings: apple,spi: Add t6020-spi compatible
ASoC: dt-bindings: apple,mca: Add t6020-mca compatible
dt-bindings: dma: apple,admac: Add t6020-admac compatible
dt-bindings: clock: apple,nco: Add t6020-nco compatible
dt-bindings: watchdog: apple,wdt: Add t6020-wdt compatible
dt-bindings: spmi: apple,spmi: Add t6020-spmi compatible
dt-bindings: mfd: apple,smc: Add t6020-smc compatible
dt-bindings: net: bcm4329-fmac: Add BCM4388 PCI compatible
dt-bindings: net: bcm4377-bluetooth: Add BCM4388 compatible
dt-bindings: nvme: apple: Add apple,t6020-nvme-ans2 compatible
dt-bindings: iommu: apple,sart: Add apple,t6020-sart compatible
dt-bindings: gpu: apple,agx: Add agx-{g14s,g14c,g14d} compatibles
dt-bindings: mailbox: apple,mailbox: Add t6020 compatible
dt-bindings: pinctrl: apple,pinctrl: Add apple,t6020-pinctrl compatible
dt-bindings: iommu: dart: Add apple,t6020-dart compatible
...
Link: https://lore.kernel.org/r/20250920123028.49973-1-sven@kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/nvme/host/apple.c | 197 | ||||
| -rw-r--r-- | drivers/pinctrl/pinctrl-apple-gpio.c | 1 | ||||
| -rw-r--r-- | drivers/pmdomain/apple/pmgr-pwrstate.c | 1 | ||||
| -rw-r--r-- | drivers/soc/apple/Kconfig | 3 | ||||
| -rw-r--r-- | drivers/soc/apple/mailbox.c | 19 | ||||
| -rw-r--r-- | drivers/soc/apple/sart.c | 60 | ||||
| -rw-r--r-- | drivers/spi/spi-apple.c | 1 |
7 files changed, 216 insertions, 66 deletions
diff --git a/drivers/nvme/host/apple.c b/drivers/nvme/host/apple.c index 1286c31320e6..f35d3f71d14f 100644 --- a/drivers/nvme/host/apple.c +++ b/drivers/nvme/host/apple.c @@ -35,7 +35,6 @@ #include "nvme.h" #define APPLE_ANS_BOOT_TIMEOUT USEC_PER_SEC -#define APPLE_ANS_MAX_QUEUE_DEPTH 64 #define APPLE_ANS_COPROC_CPU_CONTROL 0x44 #define APPLE_ANS_COPROC_CPU_CONTROL_RUN BIT(4) @@ -75,6 +74,8 @@ #define APPLE_NVME_AQ_DEPTH 2 #define APPLE_NVME_AQ_MQ_TAG_DEPTH (APPLE_NVME_AQ_DEPTH - 1) +#define APPLE_NVME_IOSQES 7 + /* * These can be higher, but we need to ensure that any command doesn't * require an sg allocation that needs more than a page of data. @@ -142,6 +143,7 @@ struct apple_nvme_queue { u32 __iomem *sq_db; u32 __iomem *cq_db; + u16 sq_tail; u16 cq_head; u8 cq_phase; @@ -166,11 +168,17 @@ struct apple_nvme_iod { struct scatterlist *sg; }; +struct apple_nvme_hw { + bool has_lsq_nvmmu; + u32 max_queue_depth; +}; + struct apple_nvme { struct device *dev; void __iomem *mmio_coproc; void __iomem *mmio_nvme; + const struct apple_nvme_hw *hw; struct device **pd_dev; struct device_link **pd_link; @@ -215,10 +223,12 @@ static inline struct apple_nvme *queue_to_apple_nvme(struct apple_nvme_queue *q) static unsigned int apple_nvme_queue_depth(struct apple_nvme_queue *q) { - if (q->is_adminq) + struct apple_nvme *anv = queue_to_apple_nvme(q); + + if (q->is_adminq && anv->hw->has_lsq_nvmmu) return APPLE_NVME_AQ_DEPTH; - return APPLE_ANS_MAX_QUEUE_DEPTH; + return anv->hw->max_queue_depth; } static void apple_nvme_rtkit_crashed(void *cookie, const void *crashlog, size_t crashlog_size) @@ -280,7 +290,28 @@ static void apple_nvmmu_inval(struct apple_nvme_queue *q, unsigned int tag) "NVMMU TCB invalidation failed\n"); } -static void apple_nvme_submit_cmd(struct apple_nvme_queue *q, +static void apple_nvme_submit_cmd_t8015(struct apple_nvme_queue *q, + struct nvme_command *cmd) +{ + struct apple_nvme *anv = queue_to_apple_nvme(q); + + spin_lock_irq(&anv->lock); + + if (q->is_adminq) + memcpy(&q->sqes[q->sq_tail], cmd, sizeof(*cmd)); + else + memcpy((void *)q->sqes + (q->sq_tail << APPLE_NVME_IOSQES), + cmd, sizeof(*cmd)); + + if (++q->sq_tail == anv->hw->max_queue_depth) + q->sq_tail = 0; + + writel(q->sq_tail, q->sq_db); + spin_unlock_irq(&anv->lock); +} + + +static void apple_nvme_submit_cmd_t8103(struct apple_nvme_queue *q, struct nvme_command *cmd) { struct apple_nvme *anv = queue_to_apple_nvme(q); @@ -590,7 +621,8 @@ static inline void apple_nvme_handle_cqe(struct apple_nvme_queue *q, __u16 command_id = READ_ONCE(cqe->command_id); struct request *req; - apple_nvmmu_inval(q, command_id); + if (anv->hw->has_lsq_nvmmu) + apple_nvmmu_inval(q, command_id); req = nvme_find_rq(apple_nvme_queue_tagset(anv, q), command_id); if (unlikely(!req)) { @@ -685,7 +717,7 @@ static int apple_nvme_create_cq(struct apple_nvme *anv) c.create_cq.opcode = nvme_admin_create_cq; c.create_cq.prp1 = cpu_to_le64(anv->ioq.cq_dma_addr); c.create_cq.cqid = cpu_to_le16(1); - c.create_cq.qsize = cpu_to_le16(APPLE_ANS_MAX_QUEUE_DEPTH - 1); + c.create_cq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1); c.create_cq.cq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG | NVME_CQ_IRQ_ENABLED); c.create_cq.irq_vector = cpu_to_le16(0); @@ -713,7 +745,7 @@ static int apple_nvme_create_sq(struct apple_nvme *anv) c.create_sq.opcode = nvme_admin_create_sq; c.create_sq.prp1 = cpu_to_le64(anv->ioq.sq_dma_addr); c.create_sq.sqid = cpu_to_le16(1); - c.create_sq.qsize = cpu_to_le16(APPLE_ANS_MAX_QUEUE_DEPTH - 1); + c.create_sq.qsize = cpu_to_le16(anv->hw->max_queue_depth - 1); c.create_sq.sq_flags = cpu_to_le16(NVME_QUEUE_PHYS_CONTIG); c.create_sq.cqid = cpu_to_le16(1); @@ -765,7 +797,12 @@ static blk_status_t apple_nvme_queue_rq(struct blk_mq_hw_ctx *hctx, } nvme_start_request(req); - apple_nvme_submit_cmd(q, cmnd); + + if (anv->hw->has_lsq_nvmmu) + apple_nvme_submit_cmd_t8103(q, cmnd); + else + apple_nvme_submit_cmd_t8015(q, cmnd); + return BLK_STS_OK; out_free_cmd: @@ -970,11 +1007,13 @@ static const struct blk_mq_ops apple_nvme_mq_ops = { static void apple_nvme_init_queue(struct apple_nvme_queue *q) { unsigned int depth = apple_nvme_queue_depth(q); + struct apple_nvme *anv = queue_to_apple_nvme(q); q->cq_head = 0; q->cq_phase = 1; - memset(q->tcbs, 0, - APPLE_ANS_MAX_QUEUE_DEPTH * sizeof(struct apple_nvmmu_tcb)); + if (anv->hw->has_lsq_nvmmu) + memset(q->tcbs, 0, anv->hw->max_queue_depth + * sizeof(struct apple_nvmmu_tcb)); memset(q->cqes, 0, depth * sizeof(struct nvme_completion)); WRITE_ONCE(q->enabled, true); wmb(); /* ensure the first interrupt sees the initialization */ @@ -1069,49 +1108,55 @@ static void apple_nvme_reset_work(struct work_struct *work) dma_set_max_seg_size(anv->dev, 0xffffffff); - /* - * Enable NVMMU and linear submission queues. - * While we could keep those disabled and pretend this is slightly - * more common NVMe controller we'd still need some quirks (e.g. - * sq entries will be 128 bytes) and Apple might drop support for - * that mode in the future. - */ - writel(APPLE_ANS_LINEAR_SQ_EN, - anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL); + if (anv->hw->has_lsq_nvmmu) { + /* + * Enable NVMMU and linear submission queues which is required + * since T6000. + */ + writel(APPLE_ANS_LINEAR_SQ_EN, + anv->mmio_nvme + APPLE_ANS_LINEAR_SQ_CTRL); - /* Allow as many pending command as possible for both queues */ - writel(APPLE_ANS_MAX_QUEUE_DEPTH | (APPLE_ANS_MAX_QUEUE_DEPTH << 16), - anv->mmio_nvme + APPLE_ANS_MAX_PEND_CMDS_CTRL); + /* Allow as many pending command as possible for both queues */ + writel(anv->hw->max_queue_depth + | (anv->hw->max_queue_depth << 16), anv->mmio_nvme + + APPLE_ANS_MAX_PEND_CMDS_CTRL); - /* Setup the NVMMU for the maximum admin and IO queue depth */ - writel(APPLE_ANS_MAX_QUEUE_DEPTH - 1, - anv->mmio_nvme + APPLE_NVMMU_NUM_TCBS); + /* Setup the NVMMU for the maximum admin and IO queue depth */ + writel(anv->hw->max_queue_depth - 1, + anv->mmio_nvme + APPLE_NVMMU_NUM_TCBS); - /* - * This is probably a chicken bit: without it all commands where any PRP - * is set to zero (including those that don't use that field) fail and - * the co-processor complains about "completed with err BAD_CMD-" or - * a "NULL_PRP_PTR_ERR" in the syslog - */ - writel(readl(anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL) & - ~APPLE_ANS_PRP_NULL_CHECK, - anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL); + /* + * This is probably a chicken bit: without it all commands + * where any PRP is set to zero (including those that don't use + * that field) fail and the co-processor complains about + * "completed with err BAD_CMD-" or a "NULL_PRP_PTR_ERR" in the + * syslog + */ + writel(readl(anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL) & + ~APPLE_ANS_PRP_NULL_CHECK, + anv->mmio_nvme + APPLE_ANS_UNKNOWN_CTRL); + } /* Setup the admin queue */ - aqa = APPLE_NVME_AQ_DEPTH - 1; + if (anv->hw->has_lsq_nvmmu) + aqa = APPLE_NVME_AQ_DEPTH - 1; + else + aqa = anv->hw->max_queue_depth - 1; aqa |= aqa << 16; writel(aqa, anv->mmio_nvme + NVME_REG_AQA); writeq(anv->adminq.sq_dma_addr, anv->mmio_nvme + NVME_REG_ASQ); writeq(anv->adminq.cq_dma_addr, anv->mmio_nvme + NVME_REG_ACQ); - /* Setup NVMMU for both queues */ - writeq(anv->adminq.tcb_dma_addr, - anv->mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE); - writeq(anv->ioq.tcb_dma_addr, - anv->mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE); + if (anv->hw->has_lsq_nvmmu) { + /* Setup NVMMU for both queues */ + writeq(anv->adminq.tcb_dma_addr, + anv->mmio_nvme + APPLE_NVMMU_ASQ_TCB_BASE); + writeq(anv->ioq.tcb_dma_addr, + anv->mmio_nvme + APPLE_NVMMU_IOSQ_TCB_BASE); + } anv->ctrl.sqsize = - APPLE_ANS_MAX_QUEUE_DEPTH - 1; /* 0's based queue depth */ + anv->hw->max_queue_depth - 1; /* 0's based queue depth */ anv->ctrl.cap = readq(anv->mmio_nvme + NVME_REG_CAP); dev_dbg(anv->dev, "Enabling controller now"); @@ -1282,8 +1327,9 @@ static int apple_nvme_alloc_tagsets(struct apple_nvme *anv) * both queues. The admin queue gets the first APPLE_NVME_AQ_DEPTH which * must be marked as reserved in the IO queue. */ - anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH; - anv->tagset.queue_depth = APPLE_ANS_MAX_QUEUE_DEPTH - 1; + if (anv->hw->has_lsq_nvmmu) + anv->tagset.reserved_tags = APPLE_NVME_AQ_DEPTH; + anv->tagset.queue_depth = anv->hw->max_queue_depth - 1; anv->tagset.timeout = NVME_IO_TIMEOUT; anv->tagset.numa_node = NUMA_NO_NODE; anv->tagset.cmd_size = sizeof(struct apple_nvme_iod); @@ -1307,6 +1353,7 @@ static int apple_nvme_queue_alloc(struct apple_nvme *anv, struct apple_nvme_queue *q) { unsigned int depth = apple_nvme_queue_depth(q); + size_t iosq_size; q->cqes = dmam_alloc_coherent(anv->dev, depth * sizeof(struct nvme_completion), @@ -1314,22 +1361,28 @@ static int apple_nvme_queue_alloc(struct apple_nvme *anv, if (!q->cqes) return -ENOMEM; - q->sqes = dmam_alloc_coherent(anv->dev, - depth * sizeof(struct nvme_command), + if (anv->hw->has_lsq_nvmmu) + iosq_size = depth * sizeof(struct nvme_command); + else + iosq_size = depth << APPLE_NVME_IOSQES; + + q->sqes = dmam_alloc_coherent(anv->dev, iosq_size, &q->sq_dma_addr, GFP_KERNEL); if (!q->sqes) return -ENOMEM; - /* - * We need the maximum queue depth here because the NVMMU only has a - * single depth configuration shared between both queues. - */ - q->tcbs = dmam_alloc_coherent(anv->dev, - APPLE_ANS_MAX_QUEUE_DEPTH * - sizeof(struct apple_nvmmu_tcb), - &q->tcb_dma_addr, GFP_KERNEL); - if (!q->tcbs) - return -ENOMEM; + if (anv->hw->has_lsq_nvmmu) { + /* + * We need the maximum queue depth here because the NVMMU only + * has a single depth configuration shared between both queues. + */ + q->tcbs = dmam_alloc_coherent(anv->dev, + anv->hw->max_queue_depth * + sizeof(struct apple_nvmmu_tcb), + &q->tcb_dma_addr, GFP_KERNEL); + if (!q->tcbs) + return -ENOMEM; + } /* * initialize phase to make sure the allocated and empty memory @@ -1413,6 +1466,12 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev) anv->adminq.is_adminq = true; platform_set_drvdata(pdev, anv); + anv->hw = of_device_get_match_data(&pdev->dev); + if (!anv->hw) { + ret = -ENODEV; + goto put_dev; + } + ret = apple_nvme_attach_genpd(anv); if (ret < 0) { dev_err_probe(dev, ret, "Failed to attach power domains"); @@ -1444,10 +1503,17 @@ static struct apple_nvme *apple_nvme_alloc(struct platform_device *pdev) goto put_dev; } - anv->adminq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB; - anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB; - anv->ioq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB; - anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB; + if (anv->hw->has_lsq_nvmmu) { + anv->adminq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_ASQ_DB; + anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB; + anv->ioq.sq_db = anv->mmio_nvme + APPLE_ANS_LINEAR_IOSQ_DB; + anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB; + } else { + anv->adminq.sq_db = anv->mmio_nvme + NVME_REG_DBS; + anv->adminq.cq_db = anv->mmio_nvme + APPLE_ANS_ACQ_DB; + anv->ioq.sq_db = anv->mmio_nvme + NVME_REG_DBS + 8; + anv->ioq.cq_db = anv->mmio_nvme + APPLE_ANS_IOCQ_DB; + } anv->sart = devm_apple_sart_get(dev); if (IS_ERR(anv->sart)) { @@ -1625,8 +1691,19 @@ static int apple_nvme_suspend(struct device *dev) static DEFINE_SIMPLE_DEV_PM_OPS(apple_nvme_pm_ops, apple_nvme_suspend, apple_nvme_resume); +static const struct apple_nvme_hw apple_nvme_t8015_hw = { + .has_lsq_nvmmu = false, + .max_queue_depth = 16, +}; + +static const struct apple_nvme_hw apple_nvme_t8103_hw = { + .has_lsq_nvmmu = true, + .max_queue_depth = 64, +}; + static const struct of_device_id apple_nvme_of_match[] = { - { .compatible = "apple,nvme-ans2" }, + { .compatible = "apple,t8015-nvme-ans2", .data = &apple_nvme_t8015_hw }, + { .compatible = "apple,nvme-ans2", .data = &apple_nvme_t8103_hw }, {}, }; MODULE_DEVICE_TABLE(of, apple_nvme_of_match); diff --git a/drivers/pinctrl/pinctrl-apple-gpio.c b/drivers/pinctrl/pinctrl-apple-gpio.c index a09daa72bfe4..e1a7bc8cf765 100644 --- a/drivers/pinctrl/pinctrl-apple-gpio.c +++ b/drivers/pinctrl/pinctrl-apple-gpio.c @@ -515,6 +515,7 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev) } static const struct of_device_id apple_gpio_pinctrl_of_match[] = { + { .compatible = "apple,t8103-pinctrl", }, { .compatible = "apple,pinctrl", }, { } }; diff --git a/drivers/pmdomain/apple/pmgr-pwrstate.c b/drivers/pmdomain/apple/pmgr-pwrstate.c index 9467235110f4..82c33cf727a8 100644 --- a/drivers/pmdomain/apple/pmgr-pwrstate.c +++ b/drivers/pmdomain/apple/pmgr-pwrstate.c @@ -306,6 +306,7 @@ err_remove: } static const struct of_device_id apple_pmgr_ps_of_match[] = { + { .compatible = "apple,t8103-pmgr-pwrstate" }, { .compatible = "apple,pmgr-pwrstate" }, {} }; diff --git a/drivers/soc/apple/Kconfig b/drivers/soc/apple/Kconfig index 6388cbe1e56b..ad6736889231 100644 --- a/drivers/soc/apple/Kconfig +++ b/drivers/soc/apple/Kconfig @@ -8,7 +8,6 @@ config APPLE_MAILBOX tristate "Apple SoC mailboxes" depends on PM depends on ARCH_APPLE || (64BIT && COMPILE_TEST) - default ARCH_APPLE help Apple SoCs have various co-processors required for certain peripherals to work (NVMe, display controller, etc.). This @@ -21,7 +20,6 @@ config APPLE_RTKIT tristate "Apple RTKit co-processor IPC protocol" depends on APPLE_MAILBOX depends on ARCH_APPLE || COMPILE_TEST - default ARCH_APPLE help Apple SoCs such as the M1 come with various co-processors running their proprietary RTKit operating system. This option enables support @@ -33,7 +31,6 @@ config APPLE_RTKIT config APPLE_SART tristate "Apple SART DMA address filter" depends on ARCH_APPLE || COMPILE_TEST - default ARCH_APPLE help Apple SART is a simple DMA address filter used on Apple SoCs such as the M1. It is usually required for the NVMe coprocessor which does diff --git a/drivers/soc/apple/mailbox.c b/drivers/soc/apple/mailbox.c index 49a0955e82d6..8f29108dc69a 100644 --- a/drivers/soc/apple/mailbox.c +++ b/drivers/soc/apple/mailbox.c @@ -47,6 +47,9 @@ #define APPLE_ASC_MBOX_I2A_RECV0 0x830 #define APPLE_ASC_MBOX_I2A_RECV1 0x838 +#define APPLE_T8015_MBOX_A2I_CONTROL 0x108 +#define APPLE_T8015_MBOX_I2A_CONTROL 0x10c + #define APPLE_M3_MBOX_CONTROL_FULL BIT(16) #define APPLE_M3_MBOX_CONTROL_EMPTY BIT(17) @@ -382,6 +385,21 @@ static int apple_mbox_probe(struct platform_device *pdev) return 0; } +static const struct apple_mbox_hw apple_mbox_t8015_hw = { + .control_full = APPLE_ASC_MBOX_CONTROL_FULL, + .control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY, + + .a2i_control = APPLE_T8015_MBOX_A2I_CONTROL, + .a2i_send0 = APPLE_ASC_MBOX_A2I_SEND0, + .a2i_send1 = APPLE_ASC_MBOX_A2I_SEND1, + + .i2a_control = APPLE_T8015_MBOX_I2A_CONTROL, + .i2a_recv0 = APPLE_ASC_MBOX_I2A_RECV0, + .i2a_recv1 = APPLE_ASC_MBOX_I2A_RECV1, + + .has_irq_controls = false, +}; + static const struct apple_mbox_hw apple_mbox_asc_hw = { .control_full = APPLE_ASC_MBOX_CONTROL_FULL, .control_empty = APPLE_ASC_MBOX_CONTROL_EMPTY, @@ -418,6 +436,7 @@ static const struct apple_mbox_hw apple_mbox_m3_hw = { static const struct of_device_id apple_mbox_of_match[] = { { .compatible = "apple,asc-mailbox-v4", .data = &apple_mbox_asc_hw }, + { .compatible = "apple,t8015-asc-mailbox", .data = &apple_mbox_t8015_hw }, { .compatible = "apple,m3-mailbox-v2", .data = &apple_mbox_m3_hw }, {} }; diff --git a/drivers/soc/apple/sart.c b/drivers/soc/apple/sart.c index afa111736899..4ff1942b82a7 100644 --- a/drivers/soc/apple/sart.c +++ b/drivers/soc/apple/sart.c @@ -25,8 +25,17 @@ #define APPLE_SART_MAX_ENTRIES 16 -/* This is probably a bitfield but the exact meaning of each bit is unknown. */ -#define APPLE_SART_FLAGS_ALLOW 0xff +/* SARTv0 registers */ +#define APPLE_SART0_CONFIG(idx) (0x00 + 4 * (idx)) +#define APPLE_SART0_CONFIG_FLAGS GENMASK(28, 24) +#define APPLE_SART0_CONFIG_SIZE GENMASK(18, 0) +#define APPLE_SART0_CONFIG_SIZE_SHIFT 12 +#define APPLE_SART0_CONFIG_SIZE_MAX GENMASK(18, 0) + +#define APPLE_SART0_PADDR(idx) (0x40 + 4 * (idx)) +#define APPLE_SART0_PADDR_SHIFT 12 + +#define APPLE_SART0_FLAGS_ALLOW 0xf /* SARTv2 registers */ #define APPLE_SART2_CONFIG(idx) (0x00 + 4 * (idx)) @@ -38,6 +47,8 @@ #define APPLE_SART2_PADDR(idx) (0x40 + 4 * (idx)) #define APPLE_SART2_PADDR_SHIFT 12 +#define APPLE_SART2_FLAGS_ALLOW 0xff + /* SARTv3 registers */ #define APPLE_SART3_CONFIG(idx) (0x00 + 4 * (idx)) @@ -48,11 +59,15 @@ #define APPLE_SART3_SIZE_SHIFT 12 #define APPLE_SART3_SIZE_MAX GENMASK(29, 0) +#define APPLE_SART3_FLAGS_ALLOW 0xff + struct apple_sart_ops { void (*get_entry)(struct apple_sart *sart, int index, u8 *flags, phys_addr_t *paddr, size_t *size); void (*set_entry)(struct apple_sart *sart, int index, u8 flags, phys_addr_t paddr_shifted, size_t size_shifted); + /* This is probably a bitfield but the exact meaning of each bit is unknown. */ + unsigned int flags_allow; unsigned int size_shift; unsigned int paddr_shift; size_t size_max; @@ -68,6 +83,39 @@ struct apple_sart { unsigned long used_entries; }; +static void sart0_get_entry(struct apple_sart *sart, int index, u8 *flags, + phys_addr_t *paddr, size_t *size) +{ + u32 cfg = readl(sart->regs + APPLE_SART0_CONFIG(index)); + phys_addr_t paddr_ = readl(sart->regs + APPLE_SART0_PADDR(index)); + size_t size_ = FIELD_GET(APPLE_SART0_CONFIG_SIZE, cfg); + + *flags = FIELD_GET(APPLE_SART0_CONFIG_FLAGS, cfg); + *size = size_ << APPLE_SART0_CONFIG_SIZE_SHIFT; + *paddr = paddr_ << APPLE_SART0_PADDR_SHIFT; +} + +static void sart0_set_entry(struct apple_sart *sart, int index, u8 flags, + phys_addr_t paddr_shifted, size_t size_shifted) +{ + u32 cfg; + + cfg = FIELD_PREP(APPLE_SART0_CONFIG_FLAGS, flags); + cfg |= FIELD_PREP(APPLE_SART0_CONFIG_SIZE, size_shifted); + + writel(paddr_shifted, sart->regs + APPLE_SART0_PADDR(index)); + writel(cfg, sart->regs + APPLE_SART0_CONFIG(index)); +} + +static struct apple_sart_ops sart_ops_v0 = { + .get_entry = sart0_get_entry, + .set_entry = sart0_set_entry, + .flags_allow = APPLE_SART0_FLAGS_ALLOW, + .size_shift = APPLE_SART0_CONFIG_SIZE_SHIFT, + .paddr_shift = APPLE_SART0_PADDR_SHIFT, + .size_max = APPLE_SART0_CONFIG_SIZE_MAX, +}; + static void sart2_get_entry(struct apple_sart *sart, int index, u8 *flags, phys_addr_t *paddr, size_t *size) { @@ -95,6 +143,7 @@ static void sart2_set_entry(struct apple_sart *sart, int index, u8 flags, static struct apple_sart_ops sart_ops_v2 = { .get_entry = sart2_get_entry, .set_entry = sart2_set_entry, + .flags_allow = APPLE_SART2_FLAGS_ALLOW, .size_shift = APPLE_SART2_CONFIG_SIZE_SHIFT, .paddr_shift = APPLE_SART2_PADDR_SHIFT, .size_max = APPLE_SART2_CONFIG_SIZE_MAX, @@ -122,6 +171,7 @@ static void sart3_set_entry(struct apple_sart *sart, int index, u8 flags, static struct apple_sart_ops sart_ops_v3 = { .get_entry = sart3_get_entry, .set_entry = sart3_set_entry, + .flags_allow = APPLE_SART3_FLAGS_ALLOW, .size_shift = APPLE_SART3_SIZE_SHIFT, .paddr_shift = APPLE_SART3_PADDR_SHIFT, .size_max = APPLE_SART3_SIZE_MAX, @@ -233,7 +283,7 @@ int apple_sart_add_allowed_region(struct apple_sart *sart, phys_addr_t paddr, if (test_and_set_bit(i, &sart->used_entries)) continue; - ret = sart_set_entry(sart, i, APPLE_SART_FLAGS_ALLOW, paddr, + ret = sart_set_entry(sart, i, sart->ops->flags_allow, paddr, size); if (ret) { dev_dbg(sart->dev, @@ -314,6 +364,10 @@ static const struct of_device_id apple_sart_of_match[] = { .compatible = "apple,t8103-sart", .data = &sart_ops_v2, }, + { + .compatible = "apple,t8015-sart", + .data = &sart_ops_v0, + }, {} }; MODULE_DEVICE_TABLE(of, apple_sart_of_match); diff --git a/drivers/spi/spi-apple.c b/drivers/spi/spi-apple.c index 6273352a2b28..2fee7057ecc9 100644 --- a/drivers/spi/spi-apple.c +++ b/drivers/spi/spi-apple.c @@ -511,6 +511,7 @@ static int apple_spi_probe(struct platform_device *pdev) } static const struct of_device_id apple_spi_of_match[] = { + { .compatible = "apple,t8103-spi", }, { .compatible = "apple,spi", }, {} }; |
