15dd0baa8Skettenis // SPDX-License-Identifier: GPL-2.0-only OR MIT 25dd0baa8Skettenis /* Copyright 2021 Alyssa Rosenzweig <alyssa@rosenzweig.io> */ 35dd0baa8Skettenis 45dd0baa8Skettenis #ifndef __APPLE_DCP_INTERNAL_H__ 55dd0baa8Skettenis #define __APPLE_DCP_INTERNAL_H__ 65dd0baa8Skettenis 75dd0baa8Skettenis #include <linux/backlight.h> 85dd0baa8Skettenis #include <linux/device.h> 95dd0baa8Skettenis #include <linux/ioport.h> 105dd0baa8Skettenis #include <linux/mutex.h> 115dd0baa8Skettenis #include <linux/mux/consumer.h> 125dd0baa8Skettenis #include <linux/phy/phy.h> 135dd0baa8Skettenis #include <linux/platform_device.h> 145dd0baa8Skettenis #include <linux/scatterlist.h> 155dd0baa8Skettenis 165dd0baa8Skettenis #include "dptxep.h" 175dd0baa8Skettenis #include "iomfb.h" 185dd0baa8Skettenis #include "iomfb_v12_3.h" 195dd0baa8Skettenis #include "iomfb_v13_3.h" 205dd0baa8Skettenis 215dd0baa8Skettenis #define DCP_MAX_PLANES 2 225dd0baa8Skettenis 235dd0baa8Skettenis struct apple_dcp; 245dd0baa8Skettenis struct apple_dcp_afkep; 255dd0baa8Skettenis 265dd0baa8Skettenis enum dcp_firmware_version { 275dd0baa8Skettenis DCP_FIRMWARE_UNKNOWN, 285dd0baa8Skettenis DCP_FIRMWARE_V_12_3, 295dd0baa8Skettenis DCP_FIRMWARE_V_13_5, 305dd0baa8Skettenis }; 315dd0baa8Skettenis 325dd0baa8Skettenis enum { 335dd0baa8Skettenis SYSTEM_ENDPOINT = 0x20, 345dd0baa8Skettenis TEST_ENDPOINT = 0x21, 355dd0baa8Skettenis DCP_EXPERT_ENDPOINT = 0x22, 365dd0baa8Skettenis DISP0_ENDPOINT = 0x23, 375dd0baa8Skettenis DPTX_ENDPOINT = 0x2a, 385dd0baa8Skettenis HDCP_ENDPOINT = 0x2b, 395dd0baa8Skettenis REMOTE_ALLOC_ENDPOINT = 0x2d, 405dd0baa8Skettenis IOMFB_ENDPOINT = 0x37, 415dd0baa8Skettenis }; 425dd0baa8Skettenis 435dd0baa8Skettenis /* Temporary backing for a chunked transfer via setDCPAVPropStart/Chunk/End */ 445dd0baa8Skettenis struct dcp_chunks { 455dd0baa8Skettenis size_t length; 465dd0baa8Skettenis void *data; 475dd0baa8Skettenis }; 485dd0baa8Skettenis 495dd0baa8Skettenis #define DCP_MAX_MAPPINGS (128) /* should be enough */ 505dd0baa8Skettenis #define MAX_DISP_REGISTERS (7) 515dd0baa8Skettenis 525dd0baa8Skettenis struct dcp_mem_descriptor { 535dd0baa8Skettenis size_t size; 545dd0baa8Skettenis void *buf; 555dd0baa8Skettenis dma_addr_t dva; 565dd0baa8Skettenis struct sg_table map; 575dd0baa8Skettenis u64 reg; 585dd0baa8Skettenis }; 595dd0baa8Skettenis 605dd0baa8Skettenis /* Limit on call stack depth (arbitrary). Some nesting is required */ 615dd0baa8Skettenis #define DCP_MAX_CALL_DEPTH 8 625dd0baa8Skettenis 635dd0baa8Skettenis typedef void (*dcp_callback_t)(struct apple_dcp *, void *, void *); 645dd0baa8Skettenis 655dd0baa8Skettenis struct dcp_channel { 665dd0baa8Skettenis dcp_callback_t callbacks[DCP_MAX_CALL_DEPTH]; 675dd0baa8Skettenis void *cookies[DCP_MAX_CALL_DEPTH]; 685dd0baa8Skettenis void *output[DCP_MAX_CALL_DEPTH]; 695dd0baa8Skettenis u16 end[DCP_MAX_CALL_DEPTH]; 705dd0baa8Skettenis 715dd0baa8Skettenis /* Current depth of the call stack. Less than DCP_MAX_CALL_DEPTH */ 725dd0baa8Skettenis u8 depth; 735dd0baa8Skettenis }; 745dd0baa8Skettenis 755dd0baa8Skettenis struct dcp_fb_reference { 765dd0baa8Skettenis struct list_head head; 775dd0baa8Skettenis struct drm_framebuffer *fb; 785dd0baa8Skettenis u32 swap_id; 795dd0baa8Skettenis }; 805dd0baa8Skettenis 815dd0baa8Skettenis #define MAX_NOTCH_HEIGHT 160 825dd0baa8Skettenis 835dd0baa8Skettenis struct dcp_brightness { 845dd0baa8Skettenis struct backlight_device *bl_dev; 855dd0baa8Skettenis u32 maximum; 865dd0baa8Skettenis u32 dac; 875dd0baa8Skettenis int nits; 885dd0baa8Skettenis int scale; 895dd0baa8Skettenis bool update; 905dd0baa8Skettenis }; 915dd0baa8Skettenis 925dd0baa8Skettenis /** laptop/AiO integrated panel parameters from DT */ 935dd0baa8Skettenis struct dcp_panel { 945dd0baa8Skettenis /// panel width in millimeter 955dd0baa8Skettenis int width_mm; 965dd0baa8Skettenis /// panel height in millimeter 975dd0baa8Skettenis int height_mm; 98172aa44cSkettenis /// panel has a mini-LED backlight 995dd0baa8Skettenis bool has_mini_led; 1005dd0baa8Skettenis }; 1015dd0baa8Skettenis 1025dd0baa8Skettenis struct apple_dcp_hw_data { 1035dd0baa8Skettenis u32 num_dptx_ports; 1045dd0baa8Skettenis }; 1055dd0baa8Skettenis 1065dd0baa8Skettenis /* TODO: move IOMFB members to its own struct */ 1075dd0baa8Skettenis struct apple_dcp { 1085dd0baa8Skettenis struct device *dev; 1095dd0baa8Skettenis struct platform_device *piodma; 1105dd0baa8Skettenis struct iommu_domain *iommu_dom; 1115dd0baa8Skettenis struct apple_rtkit *rtk; 1125dd0baa8Skettenis struct apple_crtc *crtc; 1135dd0baa8Skettenis struct apple_connector *connector; 1145dd0baa8Skettenis 1155dd0baa8Skettenis struct apple_dcp_hw_data hw; 1165dd0baa8Skettenis 1175dd0baa8Skettenis /* firmware version and compatible firmware version */ 1185dd0baa8Skettenis enum dcp_firmware_version fw_compat; 1195dd0baa8Skettenis 1205dd0baa8Skettenis /* Coprocessor control register */ 1215dd0baa8Skettenis void __iomem *coproc_reg; 1225dd0baa8Skettenis 1235dd0baa8Skettenis /* DCP has crashed */ 1245dd0baa8Skettenis bool crashed; 1255dd0baa8Skettenis 1265dd0baa8Skettenis /************* IOMFB ************************************************** 1275dd0baa8Skettenis * everything below is mostly used inside IOMFB but it could make * 1285dd0baa8Skettenis * sense keep some of the the members in apple_dcp. * 1295dd0baa8Skettenis **********************************************************************/ 1305dd0baa8Skettenis 1315dd0baa8Skettenis /* clock rate request by dcp in */ 1325dd0baa8Skettenis struct clk *clk; 1335dd0baa8Skettenis 1345dd0baa8Skettenis /* DCP shared memory */ 1355dd0baa8Skettenis void *shmem; 1365dd0baa8Skettenis 1375dd0baa8Skettenis /* Display registers mappable to the DCP */ 1385dd0baa8Skettenis struct resource *disp_registers[MAX_DISP_REGISTERS]; 1395dd0baa8Skettenis unsigned int nr_disp_registers; 1405dd0baa8Skettenis 1415dd0baa8Skettenis struct resource disp_bw_scratch_res; 1425dd0baa8Skettenis struct resource disp_bw_doorbell_res; 1435dd0baa8Skettenis u32 disp_bw_scratch_index; 1445dd0baa8Skettenis u32 disp_bw_scratch_offset; 1455dd0baa8Skettenis u32 disp_bw_doorbell_index; 1465dd0baa8Skettenis u32 disp_bw_doorbell_offset; 1475dd0baa8Skettenis 1485dd0baa8Skettenis u32 index; 1495dd0baa8Skettenis 1505dd0baa8Skettenis /* Bitmap of memory descriptors used for mappings made by the DCP */ 1515dd0baa8Skettenis DECLARE_BITMAP(memdesc_map, DCP_MAX_MAPPINGS); 1525dd0baa8Skettenis 1535dd0baa8Skettenis /* Indexed table of memory descriptors */ 1545dd0baa8Skettenis struct dcp_mem_descriptor memdesc[DCP_MAX_MAPPINGS]; 1555dd0baa8Skettenis 1565dd0baa8Skettenis struct dcp_channel ch_cmd, ch_oobcmd; 1575dd0baa8Skettenis struct dcp_channel ch_cb, ch_oobcb, ch_async, ch_oobasync; 1585dd0baa8Skettenis 1595dd0baa8Skettenis /* iomfb EP callback handlers */ 1605dd0baa8Skettenis const iomfb_cb_handler *cb_handlers; 1615dd0baa8Skettenis 1625dd0baa8Skettenis /* Active chunked transfer. There can only be one at a time. */ 1635dd0baa8Skettenis struct dcp_chunks chunks; 1645dd0baa8Skettenis 1655dd0baa8Skettenis /* Queued swap. Owned by the DCP to avoid per-swap memory allocation */ 1665dd0baa8Skettenis union { 1675dd0baa8Skettenis struct dcp_swap_submit_req_v12_3 v12_3; 1685dd0baa8Skettenis struct dcp_swap_submit_req_v13_3 v13_3; 1695dd0baa8Skettenis } swap; 1705dd0baa8Skettenis 1715dd0baa8Skettenis /* swap id of the last completed swap */ 1725dd0baa8Skettenis u32 last_swap_id; 1735dd0baa8Skettenis 1745dd0baa8Skettenis /* Current display mode */ 1755dd0baa8Skettenis bool during_modeset; 1765dd0baa8Skettenis bool valid_mode; 1775dd0baa8Skettenis struct dcp_set_digital_out_mode_req mode; 1785dd0baa8Skettenis 1795dd0baa8Skettenis /* completion for active turning true */ 1805dd0baa8Skettenis struct completion start_done; 1815dd0baa8Skettenis 1825dd0baa8Skettenis /* Is the DCP booted? */ 1835dd0baa8Skettenis bool active; 1845dd0baa8Skettenis 1855dd0baa8Skettenis /* eDP display without DP-HDMI conversion */ 1865dd0baa8Skettenis bool main_display; 1875dd0baa8Skettenis 1885dd0baa8Skettenis /* clear all surfaces on init */ 1895dd0baa8Skettenis bool surfaces_cleared; 1905dd0baa8Skettenis 1915dd0baa8Skettenis /* Modes valid for the connected display */ 1925dd0baa8Skettenis struct dcp_display_mode *modes; 1935dd0baa8Skettenis unsigned int nr_modes; 1945dd0baa8Skettenis 1955dd0baa8Skettenis /* Attributes of the connector */ 1965dd0baa8Skettenis int connector_type; 1975dd0baa8Skettenis 1985dd0baa8Skettenis /* Attributes of the connected display */ 1995dd0baa8Skettenis int width_mm, height_mm; 2005dd0baa8Skettenis 2015dd0baa8Skettenis unsigned notch_height; 2025dd0baa8Skettenis 2035dd0baa8Skettenis /* Workqueue for sending vblank events when a dcp swap is not possible */ 2045dd0baa8Skettenis struct work_struct vblank_wq; 2055dd0baa8Skettenis 2065dd0baa8Skettenis /* List of referenced drm_framebuffers which can be unreferenced 2075dd0baa8Skettenis * on the next successfully completed swap. 2085dd0baa8Skettenis */ 2095dd0baa8Skettenis struct list_head swapped_out_fbs; 2105dd0baa8Skettenis 2115dd0baa8Skettenis struct dcp_brightness brightness; 2125dd0baa8Skettenis /* Workqueue for updating the initial initial brightness */ 2135dd0baa8Skettenis struct work_struct bl_register_wq; 2145dd0baa8Skettenis struct rwlock bl_register_mutex; 215*48fd60f3Skettenis /* Workqueue for updating the brightness */ 216*48fd60f3Skettenis struct work_struct bl_update_wq; 2175dd0baa8Skettenis 2185dd0baa8Skettenis /* integrated panel if present */ 2195dd0baa8Skettenis struct dcp_panel panel; 2205dd0baa8Skettenis 2215dd0baa8Skettenis struct apple_dcp_afkep *systemep; 2225dd0baa8Skettenis struct completion systemep_done; 2235dd0baa8Skettenis 2245dd0baa8Skettenis struct apple_dcp_afkep *ibootep; 2255dd0baa8Skettenis 2265dd0baa8Skettenis struct apple_dcp_afkep *dptxep; 2275dd0baa8Skettenis 2285dd0baa8Skettenis struct dptx_port dptxport[2]; 2295dd0baa8Skettenis 2305dd0baa8Skettenis /* these fields are output port specific */ 2315dd0baa8Skettenis struct phy *phy; 2325dd0baa8Skettenis struct mux_control *xbar; 2335dd0baa8Skettenis 2345dd0baa8Skettenis struct gpio_desc *hdmi_hpd; 2355dd0baa8Skettenis struct gpio_desc *hdmi_pwren; 2365dd0baa8Skettenis struct gpio_desc *dp2hdmi_pwren; 2375dd0baa8Skettenis 2385dd0baa8Skettenis struct rwlock hpd_mutex; 2395dd0baa8Skettenis 2405dd0baa8Skettenis u32 dptx_phy; 2415dd0baa8Skettenis u32 dptx_die; 2425dd0baa8Skettenis int hdmi_hpd_irq; 2435dd0baa8Skettenis }; 2445dd0baa8Skettenis 2455dd0baa8Skettenis int dcp_backlight_register(struct apple_dcp *dcp); 246*48fd60f3Skettenis int dcp_backlight_update(struct apple_dcp *dcp); 2475dd0baa8Skettenis bool dcp_has_panel(struct apple_dcp *dcp); 2485dd0baa8Skettenis 2495dd0baa8Skettenis #define DCP_AUDIO_MAX_CHANS 15 2505dd0baa8Skettenis 2515dd0baa8Skettenis #endif /* __APPLE_DCP_INTERNAL_H__ */ 252