1 /*
2  * Copyright (c) 2022 The Chromium OS Authors
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_SUBSYS_USBC_PE_COMMON_INTERNAL_H_
8 #define ZEPHYR_SUBSYS_USBC_PE_COMMON_INTERNAL_H_
9 
10 #include <zephyr/kernel.h>
11 #include <zephyr/usb_c/usbc.h>
12 #include <zephyr/drivers/usb_c/usbc_pd.h>
13 #include <zephyr/drivers/usb_c/usbc_tc.h>
14 #include <zephyr/smf.h>
15 #include "usbc_timer.h"
16 
17 /**
18  * @brief Used in sub-machines for message transmit and receive operation
19  */
20 enum sm_msg_xmit {
21 	/* Wait for a message transmission sub-machine state */
22 	SM_WAIT_FOR_TX,
23 	/* Wait for a message reception sub-machine state */
24 	SM_WAIT_FOR_RX,
25 };
26 
27 /**
28  * @brief Used in sub-machines for message source hard reset operation
29  */
30 enum sm_hard_reset {
31 	/* Start the hard-reset sub-machine state */
32 	SM_HARD_RESET_START,
33 	/* Wait for hard-reset to complete sub-machine state */
34 	SM_HARD_RESET_WAIT,
35 };
36 
37 /**
38  * @brief Policy Engine Errors
39  */
40 enum pe_error {
41 	/** Transmit error */
42 	ERR_XMIT,
43 };
44 
45 /**
46  * @brief Policy Engine Layer States
47  */
48 enum usbc_pe_state {
49 	/** PE_SNK_Startup */
50 	PE_SNK_STARTUP,
51 	/** PE_SNK_Discovery */
52 	PE_SNK_DISCOVERY,
53 	/** PE_SNK_Wait_for_Capabilities */
54 	PE_SNK_WAIT_FOR_CAPABILITIES,
55 	/** PE_SNK_Evaluate_Capability */
56 	PE_SNK_EVALUATE_CAPABILITY,
57 	/** PE_SNK_Select_Capability */
58 	PE_SNK_SELECT_CAPABILITY,
59 	/** PE_SNK_Transition_Sink */
60 	PE_SNK_TRANSITION_SINK,
61 	/** PE_SNK_Ready */
62 	PE_SNK_READY,
63 	/** PE_SNK_Hard_Reset */
64 	PE_SNK_HARD_RESET,
65 	/** PE_SNK_Transition_to_default */
66 	PE_SNK_TRANSITION_TO_DEFAULT,
67 	/** PE_SNK_Give_Sink_Cap */
68 	PE_SNK_GIVE_SINK_CAP,
69 	/** PE_SNK_Get_Source_Cap */
70 	PE_SNK_GET_SOURCE_CAP,
71 
72 	/** PE_SRC_Startup */
73 	PE_SRC_STARTUP,
74 	/** PE_SRC_Discovery */
75 	PE_SRC_DISCOVERY,
76 	/** PE_SRC_Send_Capabilities */
77 	PE_SRC_SEND_CAPABILITIES,
78 	/** PE_SRC_Negotiate_capability */
79 	PE_SRC_NEGOTIATE_CAPABILITY,
80 	/** PE_SRC_Capability_Response */
81 	PE_SRC_CAPABILITY_RESPONSE,
82 	/** PE_SRC_Transition_Supply */
83 	PE_SRC_TRANSITION_SUPPLY,
84 	/** PE_SRC_Ready */
85 	PE_SRC_READY,
86 	/** PE_SRC_Disabled */
87 	PE_SRC_DISABLED,
88 	/** PE_SRC_Hard_Reset */
89 	PE_SRC_HARD_RESET,
90 	/** PE_SRC_Hard_Reset_Received */
91 	PE_SRC_HARD_RESET_RECEIVED,
92 	/** PE_SRC_Transition_To_Default */
93 	PE_SRC_TRANSITION_TO_DEFAULT,
94 
95 	/** PE_SNK_Soft_Reset and PE_SRC_Soft_Reset */
96 	PE_SOFT_RESET,
97 	/** PE_SNK_Chunk_Received or PE_SRC_Chunk_Received */
98 	PE_CHUNK_RECEIVED,
99 	/**PE_Send_Soft_Reset */
100 	PE_SEND_SOFT_RESET,
101 
102 	/** PE_Send_Not_Supported */
103 	PE_SEND_NOT_SUPPORTED,
104 	/** PE_DRS_Evaluate_Swap */
105 	PE_DRS_EVALUATE_SWAP,
106 	/** PE_DRS_Send_Swap */
107 	PE_DRS_SEND_SWAP,
108 	/** PE_Get_Sink_Cap */
109 	PE_GET_SINK_CAP,
110 
111 	/** PE_Suspend. Not part of the PD specification. */
112 	PE_SUSPEND,
113 
114 	/**
115 	 * NOTE: The states below should not be called directly. They're used
116 	 * internally by the state machine.
117 	 */
118 
119 	/** PE_SENDER_RESPONSE_PARENT. Not part of the PD specification. */
120 	PE_SENDER_RESPONSE_PARENT,
121 	/** PE_SRC_HARD_RESET_PARENT. Not part of the PD specification. */
122 	PE_SRC_HARD_RESET_PARENT,
123 	/** Number of PE States */
124 	PE_STATE_COUNT
125 };
126 
127 /**
128  * @brief Policy Engine Layer Flags
129  */
130 enum pe_flags {
131 	/** Accept message received from port partner */
132 	PE_FLAGS_ACCEPT = 0,
133 	/** A message we requested to be sent has been transmitted */
134 	PE_FLAGS_TX_COMPLETE = 1,
135 	/** A message sent by a port partner has been received */
136 	PE_FLAGS_MSG_RECEIVED = 2,
137 	/**
138 	 * A hard reset has been requested by the DPM but has not been sent,
139 	 * not currently used
140 	 */
141 	PE_FLAGS_HARD_RESET_PENDING = 3,
142 	/** An explicit contract is in place with our port partner */
143 	PE_FLAGS_EXPLICIT_CONTRACT = 4,
144 	/**
145 	 * Waiting for Sink Capabailities timed out.  Used for retry error
146 	 * handling
147 	 */
148 	PE_FLAGS_SNK_WAIT_CAP_TIMEOUT = 5,
149 	/**
150 	 * Flag to note current Atomic Message Sequence (AMS) is interruptible.
151 	 * If this flag is not set the AMS is non-interruptible. This flag must
152 	 * be set in the interruptible's message state entry.
153 	 */
154 	PE_FLAGS_INTERRUPTIBLE_AMS = 6,
155 	/** Flag to trigger sending a Data Role Swap */
156 	PE_FLAGS_DR_SWAP_TO_DFP = 7,
157 	/** Flag is set when an AMS is initiated by the Device Policy Manager */
158 	PE_FLAGS_DPM_INITIATED_AMS = 8,
159 	/** Flag to note message was discarded due to incoming message */
160 	PE_FLAGS_MSG_DISCARDED = 9,
161 	/** Flag to trigger sending a soft reset */
162 	PE_FLAGS_SEND_SOFT_RESET = 10,
163 	/**
164 	 * This flag is set when a Wait message is received in response to a
165 	 * Sink REQUEST
166 	 */
167 	PE_FLAGS_WAIT_SINK_REQUEST = 11,
168 	/**
169 	 * This flag is set when a Wait message is received in response to a
170 	 * Data Role Swap
171 	 */
172 	PE_FLAGS_WAIT_DATA_ROLE_SWAP = 12,
173 	/**
174 	 * This flag is set when a protocol error occurs.
175 	 */
176 	PE_FLAGS_PROTOCOL_ERROR = 13,
177 	/** This flag is set when a transmit error occurs. */
178 	PE_FLAGS_MSG_XMIT_ERROR = 14,
179 
180 	/* The Port Partner is PD connected */
181 	PE_FLAGS_PD_CONNECTED = 15,
182 	/* The Port partner has been PD connected at least once */
183 	PE_FLAGS_HAS_BEEN_PD_CONNECTED = 16,
184 	/* A Protocol Error didn't generate a Soft Reset */
185 	PE_FLAGS_PROTOCOL_ERROR_NO_SOFT_RESET = 17,
186 	/* This flag is set when the first AMS message is sent */
187 	PE_FLAGS_FIRST_MSG_SENT = 18,
188 	/** Number of PE Flags */
189 	PE_FLAGS_COUNT
190 };
191 
192 /**
193  * @brief Policy Engine State Machine Object
194  */
195 struct policy_engine {
196 	/** state machine context */
197 	struct smf_ctx ctx;
198 	/** Port device */
199 	const struct device *dev;
200 	/** state machine flags */
201 	ATOMIC_DEFINE(flags, PE_FLAGS_COUNT);
202 	/** current port power role (SOURCE or SINK) */
203 	enum tc_power_role power_role;
204 	/** current port data role (DFP or UFP) */
205 	enum tc_data_role data_role;
206 	/** port address where soft resets are sent */
207 	enum pd_packet_type soft_reset_sop;
208 	/** DPM request */
209 	enum usbc_policy_request_t dpm_request;
210 	/** generic variable used for simple in state statemachines */
211 	uint32_t submachine;
212 #ifdef CONFIG_USBC_CSM_SOURCE_ONLY
213 	/** The Sink made a valid request of the Source if true */
214 	bool snk_request_can_be_met;
215 	/** Outcome of the Sink request */
216 	enum usbc_snk_req_reply_t snk_request_reply;
217 	/** Save Sink Request Object */
218 	uint32_t snk_request;
219 	/** Present Contract stores the current Sink Request */
220 	uint32_t present_contract;
221 #endif
222 	/* Counters */
223 
224 	/**
225 	 * This counter is used to retry the Hard Reset whenever there is no
226 	 * response from the remote device.
227 	 */
228 	uint32_t hard_reset_counter;
229 
230 #ifdef CONFIG_USBC_CSM_SOURCE_ONLY
231 	/**
232 	 * This counter tracks the number of times a Source Caps message was
233 	 * sent.
234 	 */
235 	uint32_t caps_counter;
236 #endif
237 
238 	/* Timers */
239 
240 	/** tSenderResponse timer */
241 	struct usbc_timer_t pd_t_sender_response;
242 	/** tChunkingNotSupported timer */
243 	struct usbc_timer_t pd_t_chunking_not_supported;
244 	/** Time to wait before resending message after WAIT reception */
245 	struct usbc_timer_t pd_t_wait_to_resend;
246 
247 #ifdef CONFIG_USBC_CSM_SINK_ONLY
248 	/** tTypeCSinkWaitCap timer */
249 	struct usbc_timer_t pd_t_typec_sink_wait_cap;
250 	/** tPSTransition timer */
251 	struct usbc_timer_t pd_t_ps_transition;
252 	/** tSinkRequest timer */
253 	struct usbc_timer_t pd_t_sink_request;
254 #else
255 	/** tTypeCSendSourceCap timer */
256 	struct usbc_timer_t pd_t_typec_send_source_cap;
257 	/** tNoResponse timer */
258 	struct usbc_timer_t pd_t_no_response;
259 	/** tPSHardReset timer */
260 	struct usbc_timer_t pd_t_ps_hard_reset;
261 #endif /* CONFIG_USBC_CSM_SINK_ONLY */
262 };
263 
264 /**
265  * @brief First message in AMS has been sent
266  *
267  * @param dev Pointer to the device structure for the driver instance
268  */
269 void pe_first_msg_sent(const struct device *dev);
270 
271 /**
272  * @brief Sets a Policy Engine state
273  *
274  * @param dev Pointer to the device structure for the driver instance
275  * @param state next PE State to enter
276  */
277 void pe_set_state(const struct device *dev, const enum usbc_pe_state state);
278 
279 /**
280  * @brief Get the Policy Engine's current state
281  *
282  * @param dev Pointer to the device structure for the driver instance
283  * @retval current PE state
284  */
285 enum usbc_pe_state pe_get_state(const struct device *dev);
286 
287 /**
288  * @brief Get the Policy Engine's previous state
289  *
290  * @param dev Pointer to the device structure for the driver instance
291  * @retval last PE state
292  */
293 enum usbc_pe_state pe_get_last_state(const struct device *dev);
294 
295 /**
296  * @brief Send a soft reset message
297  *
298  * @param dev Pointer to the device structure for the driver instance
299  * @param type SOP* to send soft reset message
300  */
301 void pe_send_soft_reset(const struct device *dev, const enum pd_packet_type type);
302 
303 /**
304  * @brief Send a Power Delivery Data Message
305  *
306  * @param dev Pointer to the device structure for the driver instance
307  * @param type SOP* to send message
308  * @param msg PD data message to send
309  */
310 void pe_send_data_msg(const struct device *dev,
311 		   const enum pd_packet_type type,
312 		   const enum pd_data_msg_type msg);
313 
314 /**
315  * @brief Send a Power Delivery Control Message
316  *
317  * @param dev Pointer to the device structure for the driver instance
318  * @param type SOP* to send message
319  * @param msg PD control message to send
320  */
321 void pe_send_ctrl_msg(const struct device *dev,
322 		   const enum pd_packet_type type,
323 		   const enum pd_ctrl_msg_type msg);
324 
325 /**
326  * @brief Request desired voltage from source.
327  *
328  * @param dev Pointer to the device structure for the driver instance
329  * @param rdo Request Data Object to send
330  */
331 void pe_send_request_msg(const struct device *dev, const uint32_t rdo);
332 
333 /**
334  * @brief Transitions state after receiving an extended message.
335  *
336  * @param dev Pointer to the device structure for the driver instance
337  */
338 void extended_message_not_supported(const struct device *dev);
339 
340 /**
341  * @brief Check if a specific control message was received
342  *
343  * @param dev Pointer to the device structure for the driver instance
344  * @param header message header containing the message
345  * @param mt message type to check
346  * @retval true if the header contains the message type, else false
347  */
348 bool received_control_message(const struct device *dev, const union pd_header header,
349 			      const enum pd_ctrl_msg_type mt);
350 
351 /**
352  * @brief Check if a specific data message was received
353  *
354  * @param dev Pointer to the device structure for the driver instance
355  * @param header message header containing the message
356  * @param mt message type to check
357  * @param true if the header contains the message type, else false
358  */
359 bool received_data_message(const struct device *dev, const union pd_header header,
360 			   const enum pd_data_msg_type mt);
361 
362 /**
363  * @brief Check a DPM policy
364  *
365  * @param dev Pointer to the device structure for the driver instance
366  * @param pc The DPM policy to check
367  * @retval true if the DPM approves the check, else false
368  */
369 bool policy_check(const struct device *dev, const enum usbc_policy_check_t pc);
370 
371 /**
372  * @brief Notify the DPM of a policy change
373  *
374  * @param dev Pointer to the device structure for the driver instance
375  * @param notify The notification to send the DPM
376  */
377 void policy_notify(const struct device *dev, const enum usbc_policy_notify_t notify);
378 
379 /**
380  * @brief Notify the DPM of a WAIT message reception
381  *
382  * @param dev Pointer to the device structure for the driver instance
383  * @param notify Wait message to send to DPM
384  * @retval true if the Policy Engine should wait and try the action again
385  */
386 bool policy_wait_notify(const struct device *dev, const enum usbc_policy_wait_t notify);
387 
388 /**
389  * @brief Send the received source caps to the DPM
390  *
391  * @param dev Pointer to the device structure for the driver instance
392  * @param pdos pointer to pdos to send
393  * @param num_pdos number of pdos to send
394  */
395 void policy_set_src_cap(const struct device *dev, const uint32_t *pdos, const int num_pdos);
396 
397 /**
398  * @brief Check if the sink request can be met by the DPM
399  */
400 enum usbc_snk_req_reply_t policy_check_sink_request(const struct device *dev,
401 						const uint32_t request_msg);
402 
403 /**
404  * @brief Check if the Present Contract is still valid.
405  *
406  * @note The contract is considered "invalid" if the previous current/voltage
407  *	 are no longer available AND the sink fails to make a valid request.
408  */
409 bool policy_present_contract_is_valid(const struct device *dev, const uint32_t present_contract);
410 
411 /**
412  * @brief Get a Request Data Object from the DPM
413  *
414  * @param dev Pointer to the device structure for the driver instance
415  * @retval the RDO from the DPM
416  */
417 uint32_t policy_get_request_data_object(const struct device *dev);
418 
419 /**
420  * @brief Check if the sink is a default level
421  *
422  * @param dev Pointer to the device structure for the driver instance
423  * @retval true if sink is at default value, else false
424  */
425 bool policy_is_snk_at_default(const struct device *dev);
426 
427 /**
428  * @brief Get sink caps from the DPM
429  *
430  * @param dev Pointer to the device structure for the driver instance
431  * @param pdos pointer to pdo sink caps
432  * @param num_pdos number of pdo sink caps
433  */
434 void policy_get_snk_cap(const struct device *dev, uint32_t **pdos, int *num_pdos);
435 
436 /**
437  * @brief Check if Source Power Supply is ready
438  */
439 bool policy_is_ps_ready(const struct device *dev);
440 
441 /**
442  * @brief Informs the Device Policy Manager that the Sink
443  *	  is unable to use the current Source Caps and should
444  *	  should enable a different set of Source Caps. True
445  *	  is returned if new Source Caps are available, else
446  *	  false.
447  */
448 bool policy_change_src_caps(const struct device *dev);
449 
450 /**
451  * @brief End and atomic messaging sequence
452  */
453 void pe_dpm_end_ams(const struct device *dev);
454 
455 /**
456  * @brief Handle common DPM requests
457  *
458  * @param dev Pointer to the device structure for the driver instance
459  * @retval true if request was handled, else false
460  */
461 bool common_dpm_requests(const struct device *dev);
462 
463 /**
464  * @brief This function must only be called in the subsystem init function.
465  *
466  * @param dev Pointer to the device structure for the driver instance.
467  */
468 void pe_subsys_init(const struct device *dev);
469 
470 /**
471  * @brief Start the Policy Engine Layer state machine. This is only called
472  *	  from the Type-C state machine.
473  *
474  * @param dev Pointer to the device structure for the driver instance
475  */
476 void pe_start(const struct device *dev);
477 
478 /**
479  * @brief Suspend the Policy Engine Layer state machine. This is only called
480  *	  from the Type-C state machine.
481  *
482  * @param dev Pointer to the device structure for the driver instance
483  */
484 void pe_suspend(const struct device *dev);
485 
486 /**
487  * @brief Run the Policy Engine Layer state machine. This is called from the
488  *	  subsystems port stack thread
489  *
490  * @param dev Pointer to the device structure for the driver instance
491  * @param dpm_request Device Policy Manager request
492  */
493 void pe_run(const struct device *dev,
494 	    const int32_t dpm_request);
495 
496 /**
497  * @brief Query if the Policy Engine is running
498  *
499  * @param dev Pointer to the device structure for the driver instance
500  *
501  * @retval TRUE if the Policy Engine is running
502  * @retval FALSE if the Policy Engine is not running
503  */
504 bool pe_is_running(const struct device *dev);
505 
506 /**
507  * @brief Informs the Policy Engine that a message was successfully sent
508  *
509  * @param dev Pointer to the device structure for the driver instance
510  */
511 void pe_message_sent(const struct device *dev);
512 
513 /**
514  * @brief Informs the Policy Engine of an error.
515  *
516  * @param dev Pointer to the device structure for the driver instance
517  * @param  e policy error
518  * @param type port partner address where error was generated
519  */
520 void pe_report_error(const struct device *dev,
521 		     const enum pe_error e,
522 		     const enum pd_packet_type type);
523 
524 /**
525  * @brief Informs the Policy Engine that a transmit message was discarded
526  *	  because of an incoming message.
527  *
528  * @param dev Pointer to the device structure for the driver instance
529  */
530 void pe_report_discard(const struct device *dev);
531 
532 /**
533  * @brief Called by the Protocol Layer to informs the Policy Engine
534  *	  that a message has been received.
535  *
536  * @param dev Pointer to the device structure for the driver instance
537  */
538 void pe_message_received(const struct device *dev);
539 
540 /**
541  * @brief Informs the Policy Engine that a hard reset was received.
542  *
543  * @param dev Pointer to the device structure for the driver instance
544  */
545 void pe_got_hard_reset(const struct device *dev);
546 
547 /**
548  * @brief Informs the Policy Engine that a soft reset was received.
549  *
550  * @param dev Pointer to the device structure for the driver instance
551  */
552 void pe_got_soft_reset(const struct device *dev);
553 
554 /**
555  * @brief Informs the Policy Engine that a hard reset was sent.
556  *
557  * @param dev Pointer to the device structure for the driver instance
558  */
559 void pe_hard_reset_sent(const struct device *dev);
560 
561 /**
562  * @brief Indicates if an explicit contract is in place
563  *
564  * @param dev Pointer to the device structure for the driver instance
565  *
566  * @retval true if an explicit contract is in place, else false
567  */
568 bool pe_is_explicit_contract(const struct device *dev);
569 
570 /*
571  * @brief Informs the Policy Engine that it should invalidate the
572  *	  explicit contract.
573  *
574  * @param dev Pointer to the device structure for the driver instance
575  */
576 void pe_invalidate_explicit_contract(const struct device *dev);
577 
578 /**
579  * @brief Return true if the PE is within an atomic messaging sequence
580  *	  that it initiated with a SOP* port partner.
581  *
582  * @note The PRL layer polls this instead of using AMS_START and AMS_END
583  *	  notification from the PE that is called out by the spec
584  *
585  * @param dev Pointer to the device structure for the driver instance
586  */
587 bool pe_dpm_initiated_ams(const struct device *dev);
588 
589 /**
590  * @brief Get the current data role
591  *
592  * @param dev Pointer to the device structure for the driver instance
593  *
594  * @retval data role
595  */
596 enum tc_data_role pe_get_data_role(const struct device *dev);
597 
598 /**
599  * @brief Sets the data role and updates the TCPC
600  *
601  * @param dev Pointer to the device structure for the driver instance
602  * @param dr Data Role to be set
603  */
604 void pe_set_data_role(const struct device *dev, enum tc_data_role dr);
605 
606 /**
607  * @brief Get the current power role
608  *
609  * @param dev Pointer to the device structure for the driver instance
610  *
611  * @retval power role
612  */
613 enum tc_power_role pe_get_power_role(const struct device *dev);
614 
615 /**
616  * @brief Get cable plug role
617  *
618  * @param dev Pointer to the device structure for the driver instance
619  *
620  * @retval cable plug role
621  */
622 enum tc_cable_plug pe_get_cable_plug(const struct device *dev);
623 
624 #endif /* ZEPHYR_SUBSYS_USBC_PE_COMMON_INTERNAL_H_ */
625