[PATCH v2 42/44] media: ipu6: Add ipu7.5 buttress support
Antti Laakso <[email protected]>
| Newsgroups | org.kernel.vger.linux-media |
|---|---|
| Message-ID | <[email protected]> |
The ipu7.5 buttress differs from ipu7 slightly, add support for ipu7.5. Also set hardware version, firmware and model names for ipu7.5. Signed-off-by: Antti Laakso <[email protected]> --- drivers/media/pci/intel/ipu6/ipu6-buttress.c | 53 +++++++++++++++++-- .../intel/ipu6/ipu6-platform-buttress-regs.h | 7 +++ drivers/media/pci/intel/ipu6/ipu6.c | 38 +++++++++++++ drivers/media/pci/intel/ipu6/ipu6.h | 1 + 4 files changed, 94 insertions(+), 5 deletions(-) diff --git a/drivers/media/pci/intel/ipu6/ipu6-buttress.c b/drivers/media/pci/intel/ipu6/ipu6-buttress.c index 74db0a37561e..105de1744dff 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-buttress.c +++ b/drivers/media/pci/intel/ipu6/ipu6-buttress.c @@ -3,6 +3,7 @@ * Copyright (C) 2013--2024 Intel Corporation */ +#include <asm/cpu_device_id.h> #include <linux/bitfield.h> #include <linux/bits.h> #include <linux/completion.h> @@ -900,11 +901,30 @@ static int ipu6_buttress_send_tsc_request(struct ipu6_device *isp) return ret; } -int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp) +static int __ipu7p5_start_tsc_sync(struct ipu6_device *isp) { - unsigned int i; + u32 val; + + val = readl(isp->base + IPU7_BUTTRESS_REG_TSC_CTL); + val |= IPU7_BUTTRESS_SEL_PB_TIMESTAMP; + writel(val, isp->base + IPU7_BUTTRESS_REG_TSC_CTL); + + for (unsigned int i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { + val = readl(isp->base + IPU7_BUTTRESS_REG_PB_TIMESTAMP_VALID); + if (val == 1) + return 0; + + usleep_range(40, 50); + } + + dev_err(&isp->pdev->dev, "TSC sync failed (timeout)\n"); + + return -ETIMEDOUT; +} - for (i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { +static int __ipu6_start_tsc_sync(struct ipu6_device *isp) +{ + for (unsigned int i = 0; i < BUTTRESS_TSC_SYNC_RESET_TRIAL_MAX; i++) { u32 val; int ret; @@ -925,6 +945,14 @@ int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp) return -ETIMEDOUT; } + +int ipu6_buttress_start_tsc_sync(struct ipu6_device *isp) +{ + if (IS_IPU7P5(isp)) + return __ipu7p5_start_tsc_sync(isp); + + return __ipu6_start_tsc_sync(isp); +} EXPORT_SYMBOL_NS_GPL(ipu6_buttress_start_tsc_sync, "INTEL_IPU6"); void ipu6_buttress_tsc_read(struct ipu6_device *isp, u64 *val) @@ -987,6 +1015,13 @@ u32 ipu7_buttress_get_isys_freq(struct ipu6_device *isp) } EXPORT_SYMBOL_NS_GPL(ipu7_buttress_get_isys_freq, "INTEL_IPU6"); +static const struct x86_cpu_id ipu7_misc_cfg_exclusion[] = { + X86_MATCH_VFM_STEPS(INTEL_PANTHERLAKE_L, 0x1, 0x1, 0), + {}, +}; + +#define IPU7_WRXREQOP_OVRD_VAL_MASK GENMASK(22, 19) + static void ipu7_buttress_setup(struct ipu6_device *isp) { struct ipu6_buttress *b = &isp->buttress; @@ -995,12 +1030,20 @@ static void ipu7_buttress_setup(struct ipu6_device *isp) /* program PB BAR */ writel(0, isp->pb_base + IPU7_GLOBAL_INTERRUPT_MASK); val = readl(isp->pb_base + IPU7_BAR2_MISC_CONFIG); + val |= 0x100U; + if (!IS_IPU7_MTL(isp) && !x86_match_cpu(ipu7_misc_cfg_exclusion)) + val |= FIELD_PREP(IPU7_WRXREQOP_OVRD_VAL_MASK, 0xf) | BIT(18); writel(val, isp->pb_base + IPU7_BAR2_MISC_CONFIG); - writel(BIT(22), isp->pb_base + IPU7_TLBID_HASH_ENABLE_63_32); - writel(BIT(1), isp->pb_base + IPU7_TLBID_HASH_ENABLE_127_96); + if (IS_IPU7P5(isp)) { + writel(BIT(14), isp->pb_base + IPU7_TLBID_HASH_ENABLE_63_32); + writel(BIT(9), isp->pb_base + IPU7_TLBID_HASH_ENABLE_95_64); + } else { + writel(BIT(22), isp->pb_base + IPU7_TLBID_HASH_ENABLE_63_32); + writel(BIT(1), isp->pb_base + IPU7_TLBID_HASH_ENABLE_127_96); + } writel(b->regs->irq_all, isp->base + b->regs->irq_clear); writel(b->regs->irq_all, isp->base + IPU7_BUTTRESS_REG_IRQ_MASK); diff --git a/drivers/media/pci/intel/ipu6/ipu6-platform-buttress-regs.h b/drivers/media/pci/intel/ipu6/ipu6-platform-buttress-regs.h index c4da72c6bd8f..57e661cc2177 100644 --- a/drivers/media/pci/intel/ipu6/ipu6-platform-buttress-regs.h +++ b/drivers/media/pci/intel/ipu6/ipu6-platform-buttress-regs.h @@ -233,6 +233,8 @@ enum { #define IPU7_BUTTRESS_REG_TSC_CMD 0x2014 #define IPU7_BUTTRESS_REG_TSC_CTL 0x2018 #define IPU7_BUTTRESS_REG_TSC_LO 0x201c +#define IPU7_BUTTRESS_REG_PB_TIMESTAMP_LO 0x2030 +#define IPU7_BUTTRESS_REG_PB_TIMESTAMP_VALID 0x2038 #define IPU7_BUTTRESS_REG_IS_WORKPOINT_REQ 0x2104 #define IPU7_BUTTRESS_REG_PS_WORKPOINT_REQ 0x2100 #define IPU7_BUTTRESS_REG_IDLE_WDT 0x218c @@ -319,8 +321,13 @@ enum { /* PB registers */ #define IPU7_GLOBAL_INTERRUPT_MASK 0x8 +#define IPU7_TLBID_HASH_ENABLE_31_0 0x30 #define IPU7_TLBID_HASH_ENABLE_63_32 0x34 +#define IPU7_TLBID_HASH_ENABLE_95_64 0x38 #define IPU7_TLBID_HASH_ENABLE_127_96 0x3c #define IPU7_BAR2_MISC_CONFIG 0x64 +/* IPU7.5 */ +#define IPU7_BUTTRESS_SEL_PB_TIMESTAMP BIT(9) + #endif /* IPU6_PLATFORM_BUTTRESS_REGS_H */ diff --git a/drivers/media/pci/intel/ipu6/ipu6.c b/drivers/media/pci/intel/ipu6/ipu6.c index a4fd7333c68b..14cd54da2022 100644 --- a/drivers/media/pci/intel/ipu6/ipu6.c +++ b/drivers/media/pci/intel/ipu6/ipu6.c @@ -197,6 +197,36 @@ static const struct ipu6_buttress_registers ipu7_buttress_regs = { .irq_sai = IPU7_BUTTRESS_IRQ_SAI_VIOLATION, }; +static const struct ipu6_buttress_registers ipu7p5_buttress_regs = { + /* Registers */ + .irq_status = IPU7_BUTTRESS_REG_IRQ_STATUS, + .irq_clear = IPU7_BUTTRESS_REG_IRQ_CLEAR, + .irq_enable = IPU7_BUTTRESS_REG_IRQ_ENABLE, + .pwr_status = IPU7_BUTTRESS_REG_PWR_STATUS, + .security_ctl = IPU7_BUTTRESS_REG_SECURITY_CTL, + .fw_reset_ctl = IPU7_BUTTRESS_REG_FW_RESET_CTL, + .fabric_cmd = IPU7_BUTTRESS_REG_TSC_CMD, + .tsw_ctl = IPU7_BUTTRESS_REG_TSC_CTL, + .tsc_lo = IPU7_BUTTRESS_REG_PB_TIMESTAMP_LO, + .wdt = IPU7_BUTTRESS_REG_IDLE_WDT, + .csr_in = IPU7_BUTTRESS_REG_CSE2IUCSR, + .csr_out = IPU7_BUTTRESS_REG_IU2CSECSR, + .db0_in = IPU7_BUTTRESS_REG_CSE2IUDB0, + .db0_out = IPU7_BUTTRESS_REG_IU2CSEDB0, + .data0_in = IPU7_BUTTRESS_REG_CSE2IUDATA0, + .data0_out = IPU7_BUTTRESS_REG_IU2CSEDATA0, + .sku_id = IPU7_BUTTRESS_REG_SKU, + + /* Bitmasks */ + .irq_is = IPU7_BUTTRESS_IRQ_IS_IRQ, + .irq_ps = IPU7_BUTTRESS_IRQ_PS_IRQ, + .irq_all = IPU7_BUTTRESS_IRQS, + .irq_events = IPU7_BUTTRESS_IRQS, + .irq_cse_ipc = IPU7_BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING, + .irq_exec_done = IPU7_BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE, + .irq_sai = IPU7_BUTTRESS_IRQ_SAI_VIOLATION, +}; + static void ipu6_pkg_dir_configure_spc(struct ipu6_device *isp, const struct ipu6_hw_variants *hw_variant, @@ -621,6 +651,14 @@ static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) isys_ctrl = &ipu7_isys_buttress_ctrl; psys_ctrl = &ipu7_psys_buttress_ctrl; break; + case PCI_DEVICE_ID_INTEL_IPU7P5: + isp->hw_ver = IPU_VERSION_7P5; + isp->cpd_fw_name = IPU7P5_FIRMWARE_NAME; + isp->model_name = IPU7P5_MEDIA_DEV_MODEL_NAME; + isp->buttress.regs = &ipu7p5_buttress_regs; + isys_ctrl = &ipu7_isys_buttress_ctrl; + psys_ctrl = &ipu7_psys_buttress_ctrl; + break; default: return dev_err_probe(dev, -ENODEV, "Unsupported IPU6 device %x\n", diff --git a/drivers/media/pci/intel/ipu6/ipu6.h b/drivers/media/pci/intel/ipu6/ipu6.h index 8a696caf4b88..72c5063d5198 100644 --- a/drivers/media/pci/intel/ipu6/ipu6.h +++ b/drivers/media/pci/intel/ipu6/ipu6.h @@ -25,6 +25,7 @@ struct ipu6_bus_device; #define IPU6EPMTL_FIRMWARE_NAME "intel/ipu/ipu6epmtl_fw.bin" #define IPU6EPADLN_FIRMWARE_NAME "intel/ipu/ipu6epadln_fw.bin" #define IPU7_FIRMWARE_NAME "intel/ipu/ipu7_fw.bin" +#define IPU7P5_FIRMWARE_NAME "intel/ipu/ipu7ptl_fw.bin" #define IPU_VERSION_6 BIT(0) /* TGL */ #define IPU_VERSION_6SE BIT(1) /* JSL */ -- 2.55.0