xref: /linux/drivers/media/platform/amd/isp4/isp4_interface.h (revision d639d9fa162aadec1ae9980c4dcf6e50bd2f8290)
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  * Copyright (C) 2025 Advanced Micro Devices, Inc.
4  */
5 
6 #ifndef _ISP4_INTERFACE_H_
7 #define _ISP4_INTERFACE_H_
8 
9 #include <drm/amd/isp.h>
10 #include <linux/mutex.h>
11 #include <linux/platform_device.h>
12 #include <linux/spinlock.h>
13 
14 struct isp4fw_resp;
15 
16 #define ISP4IF_RB_MAX 25
17 #define ISP4IF_RESP_CHAN_TO_RB_OFFSET 9
18 #define ISP4IF_RB_PMBMAP_MEM_SIZE (SZ_16M - 1)
19 #define ISP4IF_RB_PMBMAP_MEM_CHUNK \
20 	(ISP4IF_RB_PMBMAP_MEM_SIZE / (ISP4IF_RB_MAX - 1))
21 #define ISP4IF_HOST2FW_COMMAND_SIZE sizeof(struct isp4fw_cmd)
22 #define ISP4IF_MAX_NUM_HOST2FW_COMMAND 40
23 #define ISP4IF_FW_CMD_BUF_SIZE \
24 	(ISP4IF_MAX_NUM_HOST2FW_COMMAND * ISP4IF_HOST2FW_COMMAND_SIZE)
25 #define ISP4IF_RB_FULL_SLEEP_US (33 * USEC_PER_MSEC)
26 #define ISP4IF_RB_FULL_TIMEOUT_US (10 * ISP4IF_RB_FULL_SLEEP_US)
27 
28 #define ISP4IF_META_INFO_BUF_SIZE ALIGN(sizeof(struct isp4fw_meta_info), 0x8000)
29 #define ISP4IF_MAX_STREAM_BUF_COUNT 8
30 
31 #define ISP4IF_FW_LOG_RINGBUF_SIZE SZ_2M
32 
33 enum isp4if_stream_id {
34 	ISP4IF_STREAM_ID_GLOBAL = 0,
35 	ISP4IF_STREAM_ID_1 = 1,
36 	ISP4IF_STREAM_ID_MAX = 4
37 };
38 
39 enum isp4if_status {
40 	ISP4IF_STATUS_PWR_OFF,
41 	ISP4IF_STATUS_PWR_ON,
42 	ISP4IF_STATUS_FW_RUNNING,
43 	ISP4IF_FSM_STATUS_MAX
44 };
45 
46 struct isp4if_gpu_mem_info {
47 	u64 mem_size;
48 	u64 gpu_mc_addr;
49 	void *sys_addr;
50 	void *mem_handle;
51 };
52 
53 struct isp4if_img_buf_info {
54 	struct {
55 		void *sys_addr;
56 		u64 mc_addr;
57 		u32 len;
58 	} planes[3];
59 };
60 
61 struct isp4if_img_buf_node {
62 	struct list_head node;
63 	struct isp4if_img_buf_info buf_info;
64 };
65 
66 struct isp4if_cmd_element {
67 	struct list_head list;
68 	u32 seq_num;
69 	u32 cmd_id;
70 	struct completion cmd_done;
71 	atomic_t refcnt;
72 };
73 
74 struct isp4_interface {
75 	struct device *dev;
76 	void __iomem *mmio;
77 
78 	spinlock_t cmdq_lock; /* used for cmdq access */
79 	spinlock_t bufq_lock; /* used for bufq access */
80 	struct mutex isp4if_mutex; /* used to send fw cmd and read fw log */
81 
82 	struct list_head cmdq; /* commands sent to fw */
83 	struct list_head bufq; /* buffers sent to fw */
84 
85 	enum isp4if_status status;
86 	u32 host2fw_seq_num;
87 
88 	/* ISP fw buffers */
89 	struct isp4if_gpu_mem_info *fw_log_buf;
90 	struct isp4if_gpu_mem_info *fw_cmd_resp_buf;
91 	struct isp4if_gpu_mem_info *fw_mem_pool;
92 	struct isp4if_gpu_mem_info *meta_info_buf[ISP4IF_MAX_STREAM_BUF_COUNT];
93 };
94 
95 static inline void isp4if_split_addr64(u64 addr, u32 *lo, u32 *hi)
96 {
97 	if (lo)
98 		*lo = addr & 0xffffffff;
99 
100 	if (hi)
101 		*hi = addr >> 32;
102 }
103 
104 static inline u64 isp4if_join_addr64(u32 lo, u32 hi)
105 {
106 	return (((u64)hi) << 32) | (u64)lo;
107 }
108 
109 int isp4if_f2h_resp(struct isp4_interface *ispif, enum isp4if_stream_id stream,
110 		    struct isp4fw_resp *resp);
111 
112 int isp4if_send_command(struct isp4_interface *ispif, u32 cmd_id,
113 			const void *package, u32 package_size);
114 
115 int isp4if_send_command_sync(struct isp4_interface *ispif, u32 cmd_id,
116 			     const void *package, u32 package_size);
117 
118 struct isp4if_cmd_element *isp4if_rm_cmd_from_cmdq(struct isp4_interface *ispif,
119 						   u32 seq_num, u32 cmd_id);
120 
121 void isp4if_clear_cmdq(struct isp4_interface *ispif);
122 
123 void isp4if_clear_bufq(struct isp4_interface *ispif);
124 
125 void isp4if_dealloc_buffer_node(struct isp4if_img_buf_node *buf_node);
126 
127 struct isp4if_img_buf_node *
128 isp4if_alloc_buffer_node(struct isp4if_img_buf_info *buf_info);
129 
130 struct isp4if_img_buf_node *isp4if_dequeue_buffer(struct isp4_interface *ispif);
131 
132 int isp4if_queue_buffer(struct isp4_interface *ispif,
133 			struct isp4if_img_buf_node *buf_node);
134 
135 int isp4if_stop(struct isp4_interface *ispif);
136 
137 int isp4if_start(struct isp4_interface *ispif);
138 
139 int isp4if_deinit(struct isp4_interface *ispif);
140 
141 int isp4if_init(struct isp4_interface *ispif, struct device *dev,
142 		void __iomem *isp_mmio);
143 
144 #endif /* _ISP4_INTERFACE_H_ */
145