Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 190 additions & 0 deletions Documentation/devicetree/bindings/media/apple,t6041-isp.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/media/apple,t6041-isp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Apple T604x Image Signal Processor

maintainers:
- Jonathan Goyvaerts <jonathan.goyvaerts@gmail.com>

description:
The T604x 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 three DART instances.

select:
properties:
compatible:
contains:
const: apple,t6041-isp
required:
- compatible

properties:
compatible:
items:
- const: apple,t6041-isp
- const: apple,isp

reg:
items:
- description: Coprocessor registers up to its control block
- description: Mailbox interrupt registers
- description: Firmware handshake registers
- description: Mailbox doorbell registers

reg-names:
items:
- const: coproc
- const: mbox
- const: gpio
- const: mbox2

interrupts:
maxItems: 1

iommus:
items:
- description: First ISP DART stream
- description: Second ISP DART stream
- description: Third ISP DART stream

power-domains:
items:
- description: ISP system domain
- description: ISP CPU domain
- description: ISP FE domain
- description: ISP DPRX domain
- description: ISP secure domain
- description: ISP BE domain
- description: ISP CLR domain
- description: Camera sensor domain

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,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
- reg
- reg-names
- interrupts
- iommus
- power-domains
- memory-region
- memory-region-names
- apple,dart-vm-size
- apple,platform-id
- sensor-presets

additionalProperties: false

examples:
- |
#include <dt-bindings/interrupt-controller/apple-aic.h>
#include <dt-bindings/interrupt-controller/irq.h>

soc {
#address-cells = <2>;
#size-cells = <2>;

isp@580000000 {
compatible = "apple,t6041-isp", "apple,isp";
reg = <0x5 0x80000000 0x0 0x1604000>,
<0x5 0x82924000 0x0 0x40>,
<0x5 0x829241d0 0x0 0x20>,
<0x5 0x82924464 0x0 0x10>;
reg-names = "coproc", "mbox", "gpio", "mbox2";
interrupt-parent = <&aic>;
interrupts = <AIC_IRQ 0x286 IRQ_TYPE_LEVEL_HIGH>;
iommus = <&isp_dart0 0>, <&isp_dart1 0>, <&isp_dart2 0>;
power-domains = <&ps_isp_sys>, <&ps_isp_cpu>, <&ps_isp_fe>,
<&ps_isp_dprx>, <&ps_isp_secure>, <&ps_isp_be>,
<&ps_isp_clr>, <&ps_ispsens0>;
memory-region = <&isp_fw_text>, <&isp_fw_data>, <&isp_heap>;
memory-region-names = "text", "data", "heap";
apple,dart-vm-size = /bits/ 64 <0xde600000>;
apple,platform-id = <5>;
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>;
};
};
};
};
72 changes: 65 additions & 7 deletions drivers/media/platform/apple/isp/isp-cam.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static const struct isp_setfile isp_setfiles[] = {
[ISP_IMX814_2123_01] = {0x814, 0x21230101, "apple/isp_2123_01XX.dat", 0xed54},
[ISP_IMX853_7622_01] = {0x853, 0x76220112, "apple/isp_7622_01XX.dat", 0x247f8},
[ISP_IMX913_7523_01] = {0x913, 0x75230107, "apple/isp_7523_01XX.dat", 0x247f8},
[ISP_IMX958_2224_01] = {0x958, 0x22240106, "apple/isp_2224_01XX.dat", 0x6ff4},
[ISP_VD56G0_6221_01] = {0xd56, 0x62210102, "apple/isp_6221_01XX.dat", 0x1b80},
[ISP_VD56G0_6222_01] = {0xd56, 0x62220102, "apple/isp_6222_01XX.dat", 0x1b80},
};
Expand Down Expand Up @@ -158,6 +159,10 @@ static int isp_ch_get_sensor_id(struct apple_isp *isp, u32 ch)
case 0x913:
id = ISP_IMX913_7523_01;
break;
case 0x958:
/* Section 0x50f of 2224 names sensor 0x958; 2924's names 0x614. */
id = ISP_IMX958_2224_01;
break;
case 0xd56:
id = ISP_VD56G0_6221_01;
break;
Expand Down Expand Up @@ -228,10 +233,14 @@ static int isp_ch_cache_sensor_info(struct apple_isp *isp, u32 ch)

dev_dbg(isp->dev, "found sensor %x on ch %d\n", args->version, ch);

/* The metadata buffers are allocated for the sizes the driver knows. */
/*
* The metadata buffers are allocated for the sizes the driver knows;
* without a capture metadata pool its size is not used.
*/
if (isp->hw->fw_abi == ISP_FW_ABI_H17 &&
(args->unk_68 != isp->hw->meta_size ||
args->unk_78 != isp->hw->capture_meta_size)) {
(isp->hw->capture_meta_size &&
args->unk_78 != isp->hw->capture_meta_size))) {
dev_err(isp->dev,
"metadata sizes 0x%x/0x%x, expected 0x%x/0x%x\n",
args->unk_68, args->unk_78, isp->hw->meta_size,
Expand All @@ -245,7 +254,8 @@ static int isp_ch_cache_sensor_info(struct apple_isp *isp, u32 ch)
err = isp_ch_get_sensor_id(isp, ch);
if (err ||
(fmt->id != ISP_IMX248_1820_01 && fmt->id != ISP_IMX558_1921_01 &&
fmt->id != ISP_IMX558_1925_03 && fmt->id != ISP_IMX364_8720_01)) {
fmt->id != ISP_IMX558_1925_03 && fmt->id != ISP_IMX364_8720_01 &&
fmt->id != ISP_IMX958_2224_01)) {
dev_err(isp->dev,
"ch %d: unsupported sensor. Please file a bug report with hardware info & dmesg trace.\n",
ch);
Expand Down Expand Up @@ -334,6 +344,49 @@ int apple_isp_detect_camera(struct apple_isp *isp)
return err;
}

/*
* A setfile is a chain of { le32 size, le32 0, le32 tag, payload } sections
* from 0x14 on, size counting what follows it. The lens shading sections
* hold 18-byte table records after a 10-byte header: { ?, 0x20, 0x20,
* offset lo, offset hi, 0, 0, width, height }. The xx24 setfiles keep the
* row stride (2 * width) in "offset hi"; the H17 firmware reads it as the
* offset's high half ("baseHi") and faults far past the file. Their xx25
* twins are the same tables with it zeroed, as macOS hands them over.
*/
static void isp_setfile_fixup_h17(void *data, size_t len)
{
size_t off = 0x14;

while (off + 12 <= len) {
u32 size = get_unaligned_le32(data + off);
size_t end = off + 4 + size;
size_t rec;
int i;

if (size < 8 || end > len)
break;

switch (get_unaligned_le32(data + off + 8)) {
case 0xc003:
case 0xc01b:
case 0xc01c:
case 0xc01f:
case 0xc021:
rec = off + 12 + 10;
for (i = 0; i < 16 && rec + 18 <= end; i++, rec += 18) {
if (get_unaligned_le16(data + rec + 2) != 0x20 ||
get_unaligned_le16(data + rec + 4) != 0x20)
break;
if (get_unaligned_le16(data + rec + 8) ==
2 * get_unaligned_le16(data + rec + 14))
put_unaligned_le16(0, data + rec + 8);
}
break;
}
off = end;
}
}

static int isp_ch_load_setfile(struct apple_isp *isp, u32 ch)
{
struct isp_format *fmt = isp_get_format(isp, ch);
Expand Down Expand Up @@ -372,6 +425,8 @@ static int isp_ch_load_setfile(struct apple_isp *isp, u32 ch)
memcpy(isp->data_surf->virt, fw->data, len);
memset(isp->data_surf->virt + len, 0, setfile->size - len);
release_firmware(fw);
if (isp->hw->fw_abi == ISP_FW_ABI_H17)
isp_setfile_fixup_h17(isp->data_surf->virt, len);

return isp_cmd_ch_set_file_load(isp, ch, isp->data_surf->iova,
setfile->size);
Expand Down Expand Up @@ -406,10 +461,13 @@ static int isp_ch_configure_pools(struct apple_isp *isp, u32 ch)
if (err)
return err;

err = isp_cmd_ch_buffer_pool_config_set(isp, ch,
CISP_POOL_TYPE_META_CAPTURE);
if (err)
return err;
/* H17 firmware without capture metadata has no such pool. */
if (isp->hw->fw_abi != ISP_FW_ABI_H17 || isp->hw->capture_meta_size) {
err = isp_cmd_ch_buffer_pool_config_set(isp, ch,
CISP_POOL_TYPE_META_CAPTURE);
if (err)
return err;
}

/* The H17 firmware also takes the geometry of the output buffers. */
if (isp->hw->fw_abi != ISP_FW_ABI_H17)
Expand Down
21 changes: 15 additions & 6 deletions drivers/media/platform/apple/isp/isp-cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,16 +151,24 @@ int isp_cmd_set_dsid_clr_req_base(struct apple_isp *isp, u64 dsid_clr_base,
return CISP_SEND_IN(isp, args);
}

int isp_cmd_set_dsid_clr_multi_bc(struct apple_isp *isp, u64 dsid_clr_base,
u32 dsid_clr_range)
int isp_cmd_set_dsid_clr_multi_bc(struct apple_isp *isp, const u64 *bases,
unsigned int count, u32 dsid_clr_range)
{
struct cmd_set_dsid_clr_multi_bc_reg_base args = {
.opcode = CISP_OPCODE(CISP_CMD_SET_DSID_CLR_MULTI_BC_REG_BASE),
.count = 1,
.count = count,
.dsid_clr_range = dsid_clr_range,
.dsid_clr_base = dsid_clr_base,
};
return CISP_SEND_IN(isp, args);

/* The caller, isp_set_dsid_clr(), bounds count by the array. */
if (!count)
return -EINVAL;
memcpy(args.dsid_clr_base, bases, count * sizeof(*bases));

return cisp_send(isp, &args,
offsetof(typeof(args), dsid_clr_base) +
count * sizeof(*bases), 0,
CISP_TIMEOUT);
}

int isp_cmd_pmp_ctrl_set(struct apple_isp *isp, u64 clock_scratch,
Expand Down Expand Up @@ -481,7 +489,8 @@ int isp_cmd_ch_buffer_pool_config_set_rendered(struct apple_isp *isp, u32 chan,
struct cmd_ch_buffer_pool_config_set_rendered args = {
.opcode = CISP_OPCODE(CISP_CMD_CH_BUFFER_POOL_CONFIG_SET),
.chan = chan,
.type = CISP_POOL_TYPE_RENDERED,
.type = isp->hw->scl1 ? CISP_POOL_TYPE_RENDERED_SCL1 :
CISP_POOL_TYPE_RENDERED,
.count = count,
.plane0_size = plane0_size,
.plane0_stride = plane0_stride,
Expand Down
15 changes: 10 additions & 5 deletions drivers/media/platform/apple/isp/isp-cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,20 @@ struct cmd_set_dsid_clr_req_base {
} __packed;
static_assert(sizeof(struct cmd_set_dsid_clr_req_base) == 0x14);

/* H17: a count of broadcast-clear windows and the first window */
/*
* H17: a count of broadcast-clear windows, their common range and the
* windows; the command carries only the @count windows.
*/
#define ISP_DSID_MULTI_BC_MAX 8

struct cmd_set_dsid_clr_multi_bc_reg_base {
u64 opcode;
u8 count;
u8 pad_9[3];
u32 dsid_clr_range;
u64 dsid_clr_base;
u64 dsid_clr_base[ISP_DSID_MULTI_BC_MAX];
} __packed;
static_assert(sizeof(struct cmd_set_dsid_clr_multi_bc_reg_base) == 0x18);
static_assert(sizeof(struct cmd_set_dsid_clr_multi_bc_reg_base) == 0x50);

struct cmd_pmp_ctrl_set {
u64 opcode;
Expand Down Expand Up @@ -260,8 +265,8 @@ int isp_cmd_config_get(struct apple_isp *isp, struct cmd_config_get *args);
int isp_cmd_set_isp_pmu_base(struct apple_isp *isp, u64 pmu_base);
int isp_cmd_set_dsid_clr_req_base(struct apple_isp *isp, u64 dsid_clr_base,
u32 dsid_clr_range);
int isp_cmd_set_dsid_clr_multi_bc(struct apple_isp *isp, u64 dsid_clr_base,
u32 dsid_clr_range);
int isp_cmd_set_dsid_clr_multi_bc(struct apple_isp *isp, const u64 *bases,
unsigned int count, u32 dsid_clr_range);
int isp_cmd_set_dsid_clr_req_base2(struct apple_isp *isp, u64 dsid_clr_base0,
u64 dsid_clr_base1, u64 dsid_clr_base2,
u64 dsid_clr_base3, u32 dsid_clr_range0,
Expand Down
Loading