// SPDX-License-Identifier: GPL-2.0-only OR MIT /* Copyright 2021 Alyssa Rosenzweig */ #ifndef __APPLE_DCP_INTERNAL_H__ #define __APPLE_DCP_INTERNAL_H__ #include #include #include #include #include #include #include #include #include "dptxep.h" #include "iomfb.h" #include "iomfb_v12_3.h" #include "iomfb_v13_3.h" #define DCP_MAX_PLANES 2 struct apple_dcp; struct apple_dcp_afkep; enum dcp_firmware_version { DCP_FIRMWARE_UNKNOWN, DCP_FIRMWARE_V_12_3, DCP_FIRMWARE_V_13_5, }; enum { SYSTEM_ENDPOINT = 0x20, TEST_ENDPOINT = 0x21, DCP_EXPERT_ENDPOINT = 0x22, DISP0_ENDPOINT = 0x23, DPTX_ENDPOINT = 0x2a, HDCP_ENDPOINT = 0x2b, REMOTE_ALLOC_ENDPOINT = 0x2d, IOMFB_ENDPOINT = 0x37, }; /* Temporary backing for a chunked transfer via setDCPAVPropStart/Chunk/End */ struct dcp_chunks { size_t length; void *data; }; #define DCP_MAX_MAPPINGS (128) /* should be enough */ #define MAX_DISP_REGISTERS (7) struct dcp_mem_descriptor { size_t size; void *buf; dma_addr_t dva; struct sg_table map; u64 reg; }; /* Limit on call stack depth (arbitrary). Some nesting is required */ #define DCP_MAX_CALL_DEPTH 8 typedef void (*dcp_callback_t)(struct apple_dcp *, void *, void *); struct dcp_channel { dcp_callback_t callbacks[DCP_MAX_CALL_DEPTH]; void *cookies[DCP_MAX_CALL_DEPTH]; void *output[DCP_MAX_CALL_DEPTH]; u16 end[DCP_MAX_CALL_DEPTH]; /* Current depth of the call stack. Less than DCP_MAX_CALL_DEPTH */ u8 depth; }; struct dcp_fb_reference { struct list_head head; struct drm_framebuffer *fb; u32 swap_id; }; #define MAX_NOTCH_HEIGHT 160 struct dcp_brightness { struct backlight_device *bl_dev; u32 maximum; u32 dac; int nits; int scale; bool update; }; /** laptop/AiO integrated panel parameters from DT */ struct dcp_panel { /// panel width in millimeter int width_mm; /// panel height in millimeter int height_mm; /// panel has a mini-LED backlight bool has_mini_led; }; struct apple_dcp_hw_data { u32 num_dptx_ports; }; /* TODO: move IOMFB members to its own struct */ struct apple_dcp { struct device *dev; struct platform_device *piodma; struct iommu_domain *iommu_dom; struct apple_rtkit *rtk; struct apple_crtc *crtc; struct apple_connector *connector; struct apple_dcp_hw_data hw; /* firmware version and compatible firmware version */ enum dcp_firmware_version fw_compat; /* Coprocessor control register */ void __iomem *coproc_reg; /* DCP has crashed */ bool crashed; /************* IOMFB ************************************************** * everything below is mostly used inside IOMFB but it could make * * sense keep some of the the members in apple_dcp. * **********************************************************************/ /* clock rate request by dcp in */ struct clk *clk; /* DCP shared memory */ void *shmem; /* Display registers mappable to the DCP */ struct resource *disp_registers[MAX_DISP_REGISTERS]; unsigned int nr_disp_registers; struct resource disp_bw_scratch_res; struct resource disp_bw_doorbell_res; u32 disp_bw_scratch_index; u32 disp_bw_scratch_offset; u32 disp_bw_doorbell_index; u32 disp_bw_doorbell_offset; u32 index; /* Bitmap of memory descriptors used for mappings made by the DCP */ DECLARE_BITMAP(memdesc_map, DCP_MAX_MAPPINGS); /* Indexed table of memory descriptors */ struct dcp_mem_descriptor memdesc[DCP_MAX_MAPPINGS]; struct dcp_channel ch_cmd, ch_oobcmd; struct dcp_channel ch_cb, ch_oobcb, ch_async, ch_oobasync; /* iomfb EP callback handlers */ const iomfb_cb_handler *cb_handlers; /* Active chunked transfer. There can only be one at a time. */ struct dcp_chunks chunks; /* Queued swap. Owned by the DCP to avoid per-swap memory allocation */ union { struct dcp_swap_submit_req_v12_3 v12_3; struct dcp_swap_submit_req_v13_3 v13_3; } swap; /* swap id of the last completed swap */ u32 last_swap_id; /* Current display mode */ bool during_modeset; bool valid_mode; struct dcp_set_digital_out_mode_req mode; /* completion for active turning true */ struct completion start_done; /* Is the DCP booted? */ bool active; /* eDP display without DP-HDMI conversion */ bool main_display; /* clear all surfaces on init */ bool surfaces_cleared; /* Modes valid for the connected display */ struct dcp_display_mode *modes; unsigned int nr_modes; /* Attributes of the connector */ int connector_type; /* Attributes of the connected display */ int width_mm, height_mm; unsigned notch_height; /* Workqueue for sending vblank events when a dcp swap is not possible */ struct work_struct vblank_wq; /* List of referenced drm_framebuffers which can be unreferenced * on the next successfully completed swap. */ struct list_head swapped_out_fbs; struct dcp_brightness brightness; /* Workqueue for updating the initial initial brightness */ struct work_struct bl_register_wq; struct rwlock bl_register_mutex; /* Workqueue for updating the brightness */ struct work_struct bl_update_wq; /* integrated panel if present */ struct dcp_panel panel; struct apple_dcp_afkep *systemep; struct completion systemep_done; struct apple_dcp_afkep *ibootep; struct apple_dcp_afkep *dptxep; struct dptx_port dptxport[2]; /* these fields are output port specific */ struct phy *phy; struct mux_control *xbar; struct gpio_desc *hdmi_hpd; struct gpio_desc *hdmi_pwren; struct gpio_desc *dp2hdmi_pwren; struct rwlock hpd_mutex; u32 dptx_phy; u32 dptx_die; int hdmi_hpd_irq; }; int dcp_backlight_register(struct apple_dcp *dcp); int dcp_backlight_update(struct apple_dcp *dcp); bool dcp_has_panel(struct apple_dcp *dcp); #define DCP_AUDIO_MAX_CHANS 15 #endif /* __APPLE_DCP_INTERNAL_H__ */