This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PDSP0 & PA clock disable

Hi all,

I have multiple issues that have arisen from trying to use the NetCP, when device executes Ethernet boot. I raised the issue in a different thread, but I got no answers so I will try again.

1. Why are there Rx channels in the PKTDMA for peripherals (e.g. NetCP)? Tx channel correspond to different Tx queues and the streaming port is connected to different submodules i.e. Q640 -> L2 Classification Engine, Q648 -> Ethernet Switch. For reception the flowID defines the free descriptor queue and the destination queue. The destination queue seems to be overrriden by the routing rules in the LUTs of the PDSPs, why? The streaming port switch in the NetCP allows for inputs from the GbE switch to be routed to Rx DMA channel 23 and 22. What flow will be used in this case?

2. In this thread:

http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/200415/713809.aspx#713809

the clocks of the SA, CPSW and PA were turned of and then Power to the NetCP was successfully turned off. I am able to turn the clock of for the CPSW, but not for PA, even though I think I've done all the steps required.

Also, in sprugv4b.pdf in 2.3.1 in the note it says: "Transitions from ON to OFF are never allowed." and in 2.3.2 "Transitions from Enable to
any other state are not allowed."  For CPSW transition from Enabled to SwrRstDisabled was nevertheless possible.

Any suggestions?

3. I use pdk_C6670_1_1_0_3\packages\ti\drv\exampleProjects\PA_simpleExample_exampleProject

It works when processor is set to boot in No boot mode. In Ethernet boot mode it does not work. The problem seems to be PDSP0 which does not respond to configuration packets. PA_adIP and PA_addPort work so PDSP 1 and 3 are ok, and also the configuration packet which tells where to send the response seems okay, since it is configured in the same way for Pa_addIP and PA_addMAC. I am also able to send packets over Ethernet, when pushing the packet descriptor to queue 648.

As I see it the paDownloadFirmware stops the PDSPs, writes the firmware code and restarts the PDSPs. I am not able to get ahead with this issue. PDSP0 does not answer to configuration packets.

Is there any additional information on the firmware. In sprugs4a.pdf 4.4.1 there is talk about debug registers for the PDSP. Is there any information on these so I can understand why PDSP0 does not work.

Thank you  and best regards,

eri

  • #include <ti/csl/csl_pscAux.h>
    void init_module_states();
    int ModuleStateControl(unsigned int mod_num, CSL_PSC_MODSTATE next_state);
    int NetCPPwrDomainControl(CSL_PSC_PDSTATE next_state);
    unsigned int  getNetCPPwrDomainState();
     // Initialize current Power and Clock domain states. CALL THIS FIRST! This is an internal management data base. Does not affect actual state. See ModuleStateControl()
      init_module_states();
    
      if(getNetCPPwrDomainState())
      {
      // Disable Power Domain and Clocks (CSL VERSION)
      ModuleStateControl(9, PSC_MODSTATE_DISABLE); // SA Clock Domain
      ModuleStateControl(8, PSC_MODSTATE_DISABLE); // CPSW Clock Domain
      ModuleStateControl(7, PSC_MODSTATE_DISABLE); // PA Clock Domain
      NetCPPwrDomainControl(PSC_PDSTATE_OFF); // NetCP Power Domain
      }
    
    
      // Enable Power Domain and Clocks (CSL VERSION)
      NetCPPwrDomainControl(PSC_PDSTATE_ON); // NetCP Power Domain
      ModuleStateControl(7, PSC_MODSTATE_ENABLE); // PA Clock Domain
      ModuleStateControl(8, PSC_MODSTATE_ENABLE); // CPSW Clock Domain
      ModuleStateControl(9, PSC_MODSTATE_ENABLE); // SA Clock Domain
      
      
      // This function controls power and clock domains of NetCP. 
    // Input module # and desired state to transition.
    unsigned int module_states[4];
    int ModuleStateControl(unsigned int mod_num, CSL_PSC_MODSTATE next_state)
    {
    
    int status = PASS;
    int index  = -1;
            // Make sure PSC is not in process of a state transition
            while (!CSL_PSC_isStateTransitionDone (2));
    
            // User must make sure to use appropriate state for appropriate domain
            switch(mod_num)
            {
            	       
            	case 7:
                index = 1;
            	// To enable PA clock
            	if(module_states[index] != next_state && (next_state == PSC_MODSTATE_ENABLE || next_state == PSC_MODSTATE_DISABLE))
                {
                	CSL_PSC_setModuleNextState (mod_num, next_state);
                	module_states[index] = next_state;
                }
                else
                {
                	printf("UNDEFINED STATE FOR PA CLOCK DOMAIN\n");
                	status = FAIL;
                }
                break;
                case 8:
                index = 2;
                // To enable CPSW clock
                if(module_states[index] != next_state && (next_state == PSC_MODSTATE_ENABLE || next_state == PSC_MODSTATE_DISABLE))
                {
                	CSL_PSC_setModuleNextState (mod_num, next_state);
                	module_states[index] = next_state;
                }
                else
                {
                	printf("UNDEFINED STATE FOR CPSW CLOCK DOMAIN\n");
                	status = FAIL;
                }
                break;
                case 9:
                 index = 3;
                // To enable Crypto clock 
                if(module_states[index] != next_state && (next_state == PSC_MODSTATE_ENABLE || next_state == PSC_MODSTATE_DISABLE))
                {
                	CSL_PSC_setModuleNextState (mod_num, next_state);
                	module_states[index] = next_state;
                }
                else
                {
                	printf("UNDEFINED STATE FOR SA CLOCK DOMAIN\n");
                	status = FAIL;
                }
                break;
                default:
                printf("UNDEFINED NETCP CLOCK DOMAIN\n"); 
                status = FAIL;
            }
            
            if(status == FAIL)
            {
            	printf("ABORT CLOCK SETUP!\n");
            	return status;
            }
            // Initiate transition
            CSL_PSC_startStateTransition (2);
    
            // Wait until the transition process is completed.
            while (!CSL_PSC_isStateTransitionDone (2));
    
    	   
           	if(CSL_PSC_getModuleState(mod_num) != next_state)
           	{
           		switch(next_state)
           		{
           			case PSC_MODSTATE_ENABLE:
                    module_states[index] = PSC_MODSTATE_DISABLE;
           			printf("FAILED TO START ClOCK\n");
           			status = FAIL;
           			break;
           			case PSC_MODSTATE_DISABLE:
                    module_states[index] = PSC_MODSTATE_ENABLE;
           			printf("FAILED TO STOP CLOCK\n");
           			status = FAIL;
           			break;
           			default:
           			// WE SHOULD NEVER REACH THIS CODE!
           			printf("FAILED TO FILTER PROPER STATE FOR THE MODULE\n");
           		} 
           	}
    	   
    	   return status;
    }
    
    int NetCPPwrDomainControl(CSL_PSC_PDSTATE next_state)
    {
    	int status = PASS;
    	// Make sure PSC is not in process of a state transition
            while (!CSL_PSC_isStateTransitionDone (2));
            
            switch(next_state)
            	{
            		case PSC_PDSTATE_ON:  
            		// To Enable NetCP Power domain; First check if already enabled.
            		if(module_states[0] == PSC_PDSTATE_OFF)
            		{ 
            			CSL_PSC_enablePowerDomain (2);
            			module_states[0] = next_state;
            		}
            		break;
            		case PSC_PDSTATE_OFF:
            		// To Disable NetCP Power domain; First check if already disabled.
            		if(module_states[0] == PSC_PDSTATE_ON)
            		{
            			CSL_PSC_disablePowerDomain (2);
            			module_states[0] = next_state;
            		}
            		break;
            		default:
            		printf("UNDEFINED STATE FOR NETCP POWER DOMAIN\n");
            		status = FAIL;
            	}
            	
            	if(status == FAIL)
            	{
          printf("ABORT POWER DOMAIN SETUP!\n");
            		return status;
            	}
            	// Initiate transition
            CSL_PSC_startStateTransition (2);
    
            // Wait until the transition process is completed.
            while (!CSL_PSC_isStateTransitionDone (2));
            
            // Check NetCP transitioned to correct power state
            if(CSL_PSC_getPowerDomainState(2) != next_state)
    	   	{
    	   		switch(next_state)
    	   		{
    	   			case PSC_PDSTATE_ON:
                    module_states[0] = PSC_PDSTATE_OFF;
    	   			printf("FAILED TO ENABLE NETCP PWR DOMAIN\n");
    	   			status = FAIL;
    	   			break;
    	   			case PSC_PDSTATE_OFF:
                    module_states[0] = PSC_PDSTATE_ON;
    	   			printf("FAILED TO DISABE NETCP PWR DOMAIN\n");
    	   			status = FAIL;
    	   			break;
    	   			default:
    	   			printf("FAILED TO FILTER PROPER POWER STATE FOR NETCP\n");
    	   			status = FAIL;
    	   		}
    	   	}
    	   	return status;
    }
    
    
    // Initialized current state of modules to "DISABLED"
    void init_module_states()
    {
    	int i = 0;
    
    	module_states[0] = PSC_PDSTATE_OFF;
    	for(i = 1; i < 4; i++)
    	{
    		module_states[i] = PSC_MODSTATE_DISABLE;
    	}
    }
    
    unsigned int  getNetCPPwrDomainState(){
    
        return module_states[0];
    }

    Hi Eri,

    1. The PKTDMA has both TX channels and RX channels to address to/from communicaiton with the peripheral (in this case NetCP). As you well noted NetCP has 9 TX channels all hard-mapped to a specific sub-module inside NetCP. The RX channels take data from the submodules and use a flow to determine the Free Descriptor queue and the destination queue. By default the flow ID = CH# so CH 22 and CH 23 will use Flow ID 22 and Flow ID 23. However, because the LUT's at PA have multiple entries to support independent routing for each possible match the routing info allows for overriding the flow ID and the destination queue of the flow. Else the user would be restricted to just a few destination queues for all 64/8K entries on LUT1/LUT2 respectively. On, SA it works the same the reason behind is that you may have up to 64 different tunnels which might require independent routing.

    2. To power off/on NetCP I suggest following the attached code. It can easily be included into the simple example. It is CSL based and is the proper way of powering up/down NetCP and turing on/off the clock domains. The power up and power down order is important and must be followed.

    3. For this I suggest starting to look at address 0x02000000. These are the mailbox registers. If you set the memory browser in four word columns. The first column is the number of pkts received. The third indicates how many of those packets are command packets. Row 0 is PDSP0, Row 1 is PDSP1 and so on. You can check if your packet even made it to PDSP0. Also is the packet stuck at the queue? Is the PKTDMA channel turned on?

    The PDSP registers are defined in the user guide. The control register of each PDSP will tell you if it is disabled/enabled, asleep/awake, halted/running. If the PC is not updating then that is a bad sign. Have you checked after Ethernet boot if Q900-904 have packets? It should not, the boot code should tear down the PKTDMA and QMSS, but you can try tearing it down yourself before starting any configuration if it has not been tear down yet. You might also check the status of you descriptor regions.

    1) Do the FDQ have enough packets?

    2) Do the descriptors have enough memory? Are the command buffers of enough size? (You may find this info in the doxygen and in pa.h)

    Sincerely,

    Javier