Browse Source

Don't enter Sink Standby if we don't have to

According to the USB Power Delivery Specification Revision 3.0, Version
1.1, section 7.2.3.1, we're not required to enter Sink Standby when
changing the negotiated voltage on a single PPS APDO.  Now we don't.
This is done in the PE, so the DPM doesn't have to lift a finger to
avoid the unnecessary standby.
Clara Hobbs 4 years ago
parent
commit
35c5d27f6f
2 changed files with 21 additions and 3 deletions
  1. 2
    0
      lib/include/pdb_pe.h
  2. 19
    3
      lib/src/policy_engine.c

+ 2
- 0
lib/include/pdb_pe.h View File

@@ -62,6 +62,8 @@ struct pdb_pe {
62 62
     int8_t _old_tcc_match;
63 63
     /* The index of the first PPS APDO */
64 64
     uint8_t _pps_index;
65
+    /* The index of the just-requested PPS APDO */
66
+    uint8_t _last_pps;
65 67
     /* Virtual timer for SinkPPSPeriodicTimer */
66 68
     virtual_timer_t _sink_pps_periodic_timer;
67 69
     /* Queue for the PE mailbox */

+ 19
- 3
lib/src/policy_engine.c View File

@@ -142,8 +142,9 @@ static enum policy_engine_state pe_sink_wait_cap(struct pdb_config *cfg)
142 142
 
143 143
 static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
144 144
 {
145
-    /* If we have a message, remember the index of the first PPS APDO so we can
146
-     * check if the request is for a PPS APDO in PE_SNK_Select_Cap. */
145
+    /* If we have a Source_Capabilities message, remember the index of the
146
+     * first PPS APDO so we can check if the request is for a PPS APDO in
147
+     * PE_SNK_Select_Cap. */
147 148
     if (cfg->pe._message != NULL) {
148 149
         /* Start by assuming we won't find a PPS APDO (set the index greater
149 150
          * than the maximum possible) */
@@ -156,10 +157,21 @@ static enum policy_engine_state pe_sink_eval_cap(struct pdb_config *cfg)
156 157
                 break;
157 158
             }
158 159
         }
160
+        /* New capabilities also means we can't be making a request from the
161
+         * same PPS APDO */
162
+        cfg->pe._last_pps = 8;
159 163
     }
160 164
     /* Get a message object for the request if we don't have one already */
161 165
     if (cfg->pe._last_dpm_request == NULL) {
162 166
         cfg->pe._last_dpm_request = chPoolAlloc(&pdb_msg_pool);
167
+    } else {
168
+        /* Remember the last PDO we requested if it was a PPS APDO */
169
+        if (PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request) >= cfg->pe._pps_index) {
170
+            cfg->pe._last_pps = PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request);
171
+        /* Otherwise, forget any PPS APDO we had requested */
172
+        } else {
173
+            cfg->pe._last_pps = 8;
174
+        }
163 175
     }
164 176
     /* Ask the DPM what to request */
165 177
     cfg->dpm.evaluate_capability(cfg, cfg->pe._message,
@@ -221,7 +233,9 @@ static enum policy_engine_state pe_sink_select_cap(struct pdb_config *cfg)
221 233
         if (PD_MSGTYPE_GET(cfg->pe._message) == PD_MSGTYPE_ACCEPT
222 234
                 && PD_NUMOBJ_GET(cfg->pe._message) == 0) {
223 235
             /* Transition to Sink Standby if necessary */
224
-            cfg->dpm.transition_standby(cfg);
236
+            if (PD_RDO_OBJPOS_GET(cfg->pe._last_dpm_request) != cfg->pe._last_pps) {
237
+                cfg->dpm.transition_standby(cfg);
238
+            }
225 239
 
226 240
             cfg->pe._min_power = false;
227 241
 
@@ -770,6 +784,8 @@ static THD_FUNCTION(PolicyEngine, vcfg) {
770 784
     cfg->pe._old_tcc_match = -1;
771 785
     /* Initialize the pps_index */
772 786
     cfg->pe._pps_index = 8;
787
+    /* Initialize the last_pps */
788
+    cfg->pe._last_pps = 8;
773 789
     /* Initialize the PD message header template */
774 790
     cfg->pe.hdr_template = PD_DATAROLE_UFP | PD_POWERROLE_SINK;
775 791
 

Loading…
Cancel
Save