diff --git a/Documentation/devicetree/bindings/media/apple,t6050-isp.yaml b/Documentation/devicetree/bindings/media/apple,t6050-isp.yaml index ea791487d642e..61892d3c8c17c 100644 --- a/Documentation/devicetree/bindings/media/apple,t6050-isp.yaml +++ b/Documentation/devicetree/bindings/media/apple,t6050-isp.yaml @@ -4,19 +4,23 @@ $id: http://devicetree.org/schemas/media/apple,t6050-isp.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Apple T6050 image signal processor +title: Apple T6050 Image Signal Processor maintainers: - Ryan Murray <81541646+RyanTheTide@users.noreply.github.com> + - Erik Bourget description: - The camera image signal processor of the T6050 MacBook Pros (ADT isp0). - Unlike earlier generations its ADT node lists the coprocessor window and - two PMGR windows rather than mailbox and handshake windows inside the ISP - block. Its buffers go through the three instances of the ISP DART. It is - described from the ADT so the device tree lists all of the SoC's - hardware; no driver supports this generation yet and the node stays - disabled. + The T6050 ISP controls the attached camera sensor and processes its frames + through firmware the bootloader loads. The firmware segments are described + as reserved memory mapped at the addresses the firmware runs them at. The + host exchanges commands and image buffers through streams 0 and 12 of three + DART instances. A capture watchdog must be serviced while streaming. + + Disabled hardware inventory nodes use three register windows, five interrupts, + three stream references and two power domains. Driver-ready nodes name their + five register windows and describe the host streams and individual power gates. + The bootloader supplies the reserved memory and platform ID before enabling them. select: properties: @@ -33,31 +37,124 @@ properties: - const: apple,isp reg: + minItems: 3 + maxItems: 5 + description: + Inventory nodes list the coprocessor and two PMGR windows. Named driver + resources list the coprocessor, mailbox, handshake, doorbell and watchdog. + + reg-names: items: - - description: Coprocessor registers - - description: The ISP's PMGR control window - - description: The ISP's PMGR power-state window + - const: coproc + - const: mbox + - const: gpio + - const: mbox2 + - const: wdt interrupts: - minItems: 5 + minItems: 1 maxItems: 5 iommus: - items: - - description: Stream 0 of the first ISP DART - - description: Stream 0 of the second ISP DART - - description: Stream 0 of the third ISP DART + minItems: 3 + maxItems: 6 + description: + Inventory nodes list stream 0 of each DART. Driver-ready nodes list + streams 0 and 12 of each of the three DARTs, in controller order. power-domains: - items: - - description: ISP system domain - - description: Camera sensor domain + minItems: 2 + maxItems: 8 + description: + Inventory nodes list system and sensor domains. Driver-ready nodes list + system, CPU, FE, sensor, DPRX, secure, BE and CLR domains, in that order. clocks: maxItems: 2 - status: - const: disabled + memory-region: + items: + - description: Firmware text loaded by the bootloader + - description: Firmware data loaded by the bootloader + - description: Firmware main memory window; host allocations follow it + + memory-region-names: + items: + - const: text + - const: data + - const: heap + + apple,dart-vm-size: + $ref: /schemas/types.yaml#/definitions/uint64 + description: + Size in bytes of the host allocation aperture used by the ISP driver. + + apple,platform-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Platform identifier passed in the firmware boot descriptor. + + apple,cam-connections-scheme: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Camera connection layout of the board passed in the firmware boot + descriptor. + + apple,firmware-version: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 5 + description: Version of the firmware loaded by the bootloader. + + apple,firmware-compat: + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 5 + description: Compatibility version supplied by the bootloader. + + apple,temporal-filter: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Firmware temporal-filter strength selected for the attached sensor. + + sensor-presets: + type: object + description: + Sensor firmware presets and the host output geometry associated with them. + patternProperties: + "^preset[0-9]+$": + type: object + properties: + apple,config-index: + $ref: /schemas/types.yaml#/definitions/uint32 + description: Sensor configuration index understood by the firmware + apple,input-size: + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: Input width in pixels + - description: Input height in pixels + description: Sensor input dimensions + apple,output-size: + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: Output width in pixels + - description: Output height in pixels + description: Delivered frame dimensions + apple,crop: + $ref: /schemas/types.yaml#/definitions/uint32-array + items: + - description: Horizontal crop origin in pixels + - description: Vertical crop origin in pixels + - description: Crop width in pixels + - description: Crop height in pixels + description: Cropped sensor rectangle + required: + - apple,config-index + - apple,input-size + - apple,output-size + - apple,crop + additionalProperties: false + additionalProperties: false required: - compatible @@ -65,6 +162,93 @@ required: - interrupts - iommus - power-domains - - status + +allOf: + - if: + required: + - reg-names + then: + properties: + reg: + minItems: 5 + interrupts: + maxItems: 1 + iommus: + minItems: 6 + power-domains: + minItems: 8 + clocks: false + required: + - apple,dart-vm-size + - sensor-presets + allOf: + - if: + properties: + status: + const: disabled + required: + - status + then: {} + else: + required: + - memory-region + - memory-region-names + - apple,platform-id + else: + properties: + reg: + maxItems: 3 + interrupts: + minItems: 5 + iommus: + maxItems: 3 + power-domains: + maxItems: 2 + status: + const: disabled + required: + - status additionalProperties: false + +examples: + - | + #include + #include + + soc { + #address-cells = <2>; + #size-cells = <2>; + + isp@580000000 { + compatible = "apple,t6050-isp", "apple,isp"; + reg = <0x5 0x80000000 0x0 0x1604000>, + <0x5 0x82924000 0x0 0x40>, + <0x5 0x829241d0 0x0 0x20>, + <0x5 0x82924464 0x0 0x10>, + <0x5 0xc3b50000 0x0 0x8000>; + reg-names = "coproc", "mbox", "gpio", "mbox2", "wdt"; + interrupt-parent = <&aic>; + interrupts = ; + iommus = <&isp_dart0 0>, <&isp_dart0 12>, + <&isp_dart1 0>, <&isp_dart1 12>, + <&isp_dart2 0>, <&isp_dart2 12>; + power-domains = <&ps_isp_sys>, <&ps_isp_cpu>, <&ps_isp_fe>, + <&ps_ispsens0>, <&ps_isp_dprx>, <&ps_isp_secure>, + <&ps_isp_be>, <&ps_isp_clr>; + memory-region = <&isp_fw_text>, <&isp_fw_data>, <&isp_heap>; + memory-region-names = "text", "data", "heap"; + apple,dart-vm-size = /bits/ 64 <0xde000000>; + apple,platform-id = <0x75>; + apple,cam-connections-scheme = <0x10>; + + sensor-presets { + preset0 { + apple,config-index = <5>; + apple,input-size = <1920 2160>; + apple,output-size = <1920 1080>; + apple,crop = <0 0 1920 1080>; + }; + }; + }; + }; diff --git a/drivers/media/platform/apple/isp/isp-drv-test.c b/drivers/media/platform/apple/isp/isp-drv-test.c index dbddb079a0f57..53f731234e64c 100644 --- a/drivers/media/platform/apple/isp/isp-drv-test.c +++ b/drivers/media/platform/apple/isp/isp-drv-test.c @@ -43,15 +43,16 @@ static void isp_test_dapf_in_fw_mmio(struct kunit *test) * leaves every other byte alone. The bank is plain memory here: the driver * is arm64 only, where the MMIO accessors work on it unchanged. */ -static void isp_test_dapf_program(struct kunit *test) +static void isp_test_dapf_program_mask(struct kunit *test, u32 sidmask) { static const struct isp_dapf_window windows[] = { { 0x380704000, 0x380704063 }, { 0x382824000, 0x382824004 }, }; - static const struct apple_isp_hw hw = { + const struct apple_isp_hw hw = { .dapf = windows, .num_dapf = ARRAY_SIZE(windows), + .dapf_sidmask = sidmask, }; size_t size = (ARRAY_SIZE(windows) + 1) * DAPF_WINDOW_STRIDE; u8 expect[DAPF_WINDOW_STRIDE]; @@ -76,7 +77,7 @@ static void isp_test_dapf_program(struct kunit *test) put_unaligned_le32(0, &expect[0x04]); put_unaligned_le64(windows[i].start, &expect[0x08]); put_unaligned_le64(windows[i].end, &expect[0x10]); - put_unaligned_le32(1, &expect[0x20]); + put_unaligned_le32(sidmask ?: 1, &expect[0x20]); KUNIT_EXPECT_MEMEQ_MSG(test, bank + i * DAPF_WINDOW_STRIDE, expect, sizeof(expect), "window %u", i); } @@ -86,9 +87,20 @@ static void isp_test_dapf_program(struct kunit *test) ISP_TEST_DAPF_FILL, DAPF_WINDOW_STRIDE)); } +static void isp_test_dapf_program(struct kunit *test) +{ + isp_test_dapf_program_mask(test, 0); +} + +static void isp_test_dapf_program_t6050(struct kunit *test) +{ + isp_test_dapf_program_mask(test, 0xcc3); +} + static struct kunit_case isp_dapf_test_cases[] = { KUNIT_CASE(isp_test_dapf_in_fw_mmio), KUNIT_CASE(isp_test_dapf_program), + KUNIT_CASE(isp_test_dapf_program_t6050), {} }; diff --git a/drivers/media/platform/apple/isp/isp-drv.c b/drivers/media/platform/apple/isp/isp-drv.c index 627a9bdb9e94d..21dd9cdc1be2a 100644 --- a/drivers/media/platform/apple/isp/isp-drv.c +++ b/drivers/media/platform/apple/isp/isp-drv.c @@ -255,6 +255,7 @@ static int apple_isp_map_dapf(struct apple_isp *isp) int apple_isp_program_dapf(struct apple_isp *isp) { const struct apple_isp_hw *hw = isp->hw; + u32 sidmask = hw->dapf_sidmask ?: DAPF_CTRL2_ISP; void __iomem *w; unsigned int i; @@ -264,7 +265,7 @@ int apple_isp_program_dapf(struct apple_isp *isp) writeq(hw->dapf[i].start, w + DAPF_START); writeq(hw->dapf[i].end, w + DAPF_END); writel(DAPF_CTRL0_ISP, w + DAPF_CTRL0); - writel(DAPF_CTRL2_ISP, w + DAPF_CTRL2); + writel(sidmask, w + DAPF_CTRL2); } /* Only bits 7:0 of CTRL0 and bits 63:2 of END read back. */ @@ -274,7 +275,7 @@ int apple_isp_program_dapf(struct apple_isp *isp) readq(w + DAPF_START) != hw->dapf[i].start || (readq(w + DAPF_END) | 3) != (hw->dapf[i].end | 3) || (readl(w + DAPF_CTRL0) & 0xff) != DAPF_CTRL0_ISP || - readl(w + DAPF_CTRL2) != DAPF_CTRL2_ISP) { + readl(w + DAPF_CTRL2) != sidmask) { dev_err(isp->dev, "DAPF window %u (0x%llx-0x%llx) failed readback\n", i, hw->dapf[i].start, hw->dapf[i].end); return -EIO; @@ -1141,7 +1142,82 @@ static const struct apple_isp_hw apple_isp_hw_t8142 = { .setfile_stride_fixup = true, }; +/* T6050 ISP17c: CPU-visible firmware MMIO windows and DART filters. */ +static const struct isp_mmio_window apple_isp_fw_mmio_t6050[] = { + { 0x280680000, 0x8000 }, + { 0x280900000, 0x4000 }, + { 0x284240000, 0x28000 }, + { 0x284e3c000, 0x4000 }, + { 0x286724000, 0x4000 }, + { 0x29062c000, 0x20000 }, + { 0x509660000, 0x4000 }, + { 0x2220004000, 0x14000 }, + { 0x2222004000, 0x14000 }, + { 0x2224004000, 0x14000 }, + { 0x2226004000, 0x14000 }, + { 0x2228004000, 0x14000 }, + { 0x222a004000, 0x14000 }, + { 0x222c004000, 0x14000 }, + { 0x222e004000, 0x14000 }, +}; + +static const struct isp_dapf_window apple_isp_dapf_t6050[] = { + { 0x2809003b0, 0x2809003f3 }, + { 0x280680000, 0x280687fff }, + { 0x284e3c000, 0x284e3c003 }, + { 0x29062c000, 0x290648003 }, + { 0x509660000, 0x509660003 }, + { 0x286724000, 0x286724004 }, + { 0x284240000, 0x284264000 }, + { 0x2220004000, 0x22200162fc }, + { 0x2222004000, 0x22220162fc }, + { 0x2224004000, 0x22240162fc }, + { 0x2226004000, 0x22260162fc }, + { 0x2228004000, 0x22280162fc }, + { 0x222a004000, 0x222a0162fc }, + { 0x222c004000, 0x222c0162fc }, + { 0x222e004000, 0x222e0162fc }, +}; + +static const u64 apple_isp_dsid_t6050[] = { + 0x2220016000, + 0x2222016000, + 0x2224016000, + 0x2226016000, + 0x2228016000, + 0x222a016000, + 0x222c016000, + 0x222e016000, +}; + +static const struct apple_isp_hw apple_isp_hw_t6050 = { + .gen = ISP_GEN_T6040, + .fw_abi = ISP_FW_ABI_H17, + .dsid_count = ARRAY_SIZE(apple_isp_dsid_t6050), + .dsid_clr_bases = apple_isp_dsid_t6050, + .dsid_clr_range0 = 0x2fc, + .mbox_irq_enable = ISP_MBOX_IRQ_ENABLE_T6031, + .mbox_extra_enables = true, + .scl1 = true, + .meta_size = ISP_META_SIZE_T8140, + .capture_meta_size = ISP_CAPTURE_META_SIZE_T8140, + .fw_mmio = apple_isp_fw_mmio_t6050, + .num_fw_mmio = ARRAY_SIZE(apple_isp_fw_mmio_t6050), + .dapf = apple_isp_dapf_t6050, + .num_dapf = ARRAY_SIZE(apple_isp_dapf_t6050), + .dapf_sidmask = 0xcc3, + .coproc_control = ISP_COPROC_CONTROL_T8140, + .coproc_status = ISP_COPROC_STATUS_T8140, + .coproc_quiesce = ISP_COPROC_QUIESCE_T8140, + .boot_mode = 1, + .shared_size = 0xde000000, + .fw_restore = true, + .deferred_start = true, + .setfile_stride_fixup = true, +}; + static const struct of_device_id apple_isp_of_match[] = { + { .compatible = "apple,t6050-isp", .data = &apple_isp_hw_t6050 }, { .compatible = "apple,t8103-isp", .data = &apple_isp_hw_t8103 }, { .compatible = "apple,t8112-isp", .data = &apple_isp_hw_t8112 }, { .compatible = "apple,t8122-isp", .data = &apple_isp_hw_t8122 }, diff --git a/drivers/media/platform/apple/isp/isp-drv.h b/drivers/media/platform/apple/isp/isp-drv.h index 9056c3d7af143..66fa3e1264576 100644 --- a/drivers/media/platform/apple/isp/isp-drv.h +++ b/drivers/media/platform/apple/isp/isp-drv.h @@ -162,6 +162,7 @@ struct apple_isp_hw { u64 pmu_base; int dsid_count; + const u64 *dsid_clr_bases; /* windows of the H17 multi broadcast-clear command, the unused all ones */ u8 dsid_slots; u64 dsid_clr_base0; @@ -194,6 +195,7 @@ struct apple_isp_hw { u32 mbox2_offset; /* further interrupt enable and routing words (ISP17a) */ bool mbox_irq_route; + bool mbox_extra_enables; /* coprocessor control register, 0 for ISP_COPROC_CONTROL */ u32 coproc_control; /* coprocessor status register, 0 for ISP_COPROC_STATUS */ @@ -216,6 +218,7 @@ struct apple_isp_hw { */ const struct isp_dapf_window *dapf; unsigned int num_dapf; + u32 dapf_sidmask; /* ISP_GPIO_6 boot mode */ u32 boot_mode; diff --git a/drivers/media/platform/apple/isp/isp-fw.c b/drivers/media/platform/apple/isp/isp-fw.c index 28727ef24fbb6..302b18cd189c6 100644 --- a/drivers/media/platform/apple/isp/isp-fw.c +++ b/drivers/media/platform/apple/isp/isp-fw.c @@ -251,7 +251,7 @@ static irqreturn_t apple_isp_isr_thread(int irq, void *dev) static void isp_disable_irq(struct apple_isp *isp) { isp_mbox_write32(isp, isp->hw->mbox_irq_enable, 0x0); - if (isp->hw->mbox_irq_route) { + if (isp->hw->mbox_irq_route || isp->hw->mbox_extra_enables) { isp_mbox_write32(isp, ISP_MBOX_IRQ_ENABLE1_T8140, 0x0); isp_mbox_write32(isp, ISP_MBOX_IRQ_ENABLE2_T8140, 0x0); } @@ -273,13 +273,14 @@ static int isp_enable_irq(struct apple_isp *isp) isp_dbg(isp, "about to enable interrupts...\n"); isp_mbox_write32(isp, isp->hw->mbox_irq_enable, 0xf); - if (isp->hw->mbox_irq_route) { + if (isp->hw->mbox_irq_route || isp->hw->mbox_extra_enables) { isp_mbox_write32(isp, ISP_MBOX_IRQ_ENABLE1_T8140, ISP_MBOX_IRQ_ENABLE1_T8140_VAL); isp_mbox_write32(isp, ISP_MBOX_IRQ_ENABLE2_T8140, ISP_MBOX_IRQ_ENABLE2_T8140_VAL); - isp_mbox_write32(isp, ISP_MBOX_IRQ_ROUTE_T8140, - ISP_MBOX_IRQ_ROUTE_T8140_VAL); + if (isp->hw->mbox_irq_route) + isp_mbox_write32(isp, ISP_MBOX_IRQ_ROUTE_T8140, + ISP_MBOX_IRQ_ROUTE_T8140_VAL); } return 0; @@ -934,12 +935,13 @@ static int isp_set_dsid_clr(struct apple_isp *isp) unsigned int slots = max_t(unsigned int, hw->dsid_count, hw->dsid_slots); - if (WARN_ON(hw->dsid_count > ARRAY_SIZE(used) || + if (WARN_ON((!hw->dsid_clr_bases && hw->dsid_count > ARRAY_SIZE(used)) || slots > ARRAY_SIZE(bases))) return -EINVAL; for (unsigned int i = 0; i < slots; i++) - bases[i] = i < hw->dsid_count ? used[i] : U64_MAX; + bases[i] = i < hw->dsid_count ? + (hw->dsid_clr_bases ? hw->dsid_clr_bases[i] : used[i]) : U64_MAX; return isp_cmd_set_dsid_clr_multi_bc(isp, bases, slots, hw->dsid_clr_range0);