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.

c6748e PSC初始化



大家好,c6748e PSC初始化时,寄存器PTCMD没有写入,会不会影响后续操作?

我再调试DDR时,在初始化时发现PTCMD值一直没变,DDR写入的值跳位,会不会是PTCMD影响的。

  • 只有DDR psc module不能初始化吗?其他接口的PSC module能初始化吗?
  • 都是一样的。
    举例如下:
    调用PSCModuleControl给初始化
    PSCModuleControl(SOC_PSC_0_REGS, HW_PSC_EMIFA, PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

    int PSCModuleControl(unsigned int baseAdd, unsigned int moduleId ,unsigned int powerDomain, unsigned int flags) {
        volatile unsigned int timeout = 0xFFFFFF;
        int retVal = 0;
        unsigned int status = 0;

         (读出 HWREG(baseAdd + PSC_MDCTL(moduleId))(0x1c10a08)的默认值是0x0,现在将0x3(使能)赋给该寄存器 )
         HWREG(baseAdd + PSC_MDCTL(moduleId)) = (flags & PSC_MDCTL_NEXT);
         (赋值之后该寄存器值为0x3)
       
        if (powerDomain == 0) {
          (读出PSC_PTCMD的值为0x0,赋值0x1)
            HWREG(baseAdd + PSC_PTCMD) = PSC_PTCMD_GO0;
          (赋值之后读出还是0x0)
        } else {
            HWREG(baseAdd + PSC_PTCMD) = PSC_PTCMD_GO1;
        }

        if (powerDomain == 0) {
            do {
                (PSC_PTSTAT读出默认值为0x0)
                status = HWREG(baseAdd + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT0;
            } while (status && timeout--);
       
        } else {   
            do {
                status = HWREG(baseAdd + PSC_PTSTAT) & PSC_PTSTAT_GOSTAT1;
            } while (status && timeout--);
        }

        if (timeout != 0) {

            timeout = 0xFFFFFF;
            status = flags & PSC_MDCTL_NEXT;
            do {
                timeout--;
                printf("timeout = 0x%x\n", timeout);
            } while (timeout
                    && (HWREG(baseAdd + PSC_MDSTAT(moduleId)) & PSC_MDSTAT_STATE)!= status);
        }

        if (timeout == 0) {
            retVal = -1;
        }
        return retVal;
    }

    我不知道这样算是初始化成功了吗?PSC_PTCMD一直都没有变,但是代码可以跑过。

    DDR的配置代码:

    void DEVICE_DDRConfig(void) {
        unsigned int j;
        unsigned int tmp_SDCR;

        //2. Program Power and Sleep Controller (PSC) to enable the DDR2/mDDR memory controller clock
        // Enable the Clock to EMIFDDR SDRAM

        (这里对DDR PSC使能,运行结果和上边是一样的)
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_DDR2_MDDR,
                PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);

        // Begin VTP Calibration
        VTPIO_CTL &= ~0x00000040;       // Clear POWERDN
        VTPIO_CTL &= ~0x00000080;       // Clear LOCK
        VTPIO_CTL |= 0x00002000; // Set CLKRZ in case it was cleared before (VTP looks for CLKRZ edge transition)
        VTPIO_CTL &= ~0x00002000; // Clear CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction)
        VTPIO_CTL |= 0x00002000; // Set CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction)

        j = 0;
        // Polling READY bit to see when VTP calibration is done
        while ((VTPIO_CTL & 0x00008000) == 0) {
            if (j++ > VTP_TIMEOUT) {
                printf("\tVTP Ready timeout\n");
                break;
            }
        }

        VTPIO_CTL |= 0x00000080;       // Set LOCK bit for static calibration mode
        VTPIO_CTL |= 0x00000040;       // Set POWERDN bit to power down VTP module
        // End VTP Calibration

        VTPIO_CTL |= 0x00004000; // Set IOPWRDN to allow powerdown of input receivers when PWRDNEN is set

        // **********************************************************************************************
        // Setting based 1Gb DDR2 Samsung K4T1G164QF-BCF8
        // Config DDR timings
        DRPYC1R = (0x0 << 8) |  // Reserved
                (0x1 << 7) |  // EXT_STRBEN
                (0x1 << 6) |  // PWRDNEN
                (0x0 << 3) |  // Reserved
                (0x3 << 0);     // RL
        // DRPYC1R Value = 0x000000C3

        if (DDR_DEBUG) {
            // Configure EMIF with max timings for more slack
            // Try this if memory is not stable
            DRPYC1R |= 0x7; // RL
        }

        EMIFDDR_SDCR |= 0x00800000; // Set BOOTUNLOCK

        // Settings depending on DDR2
        tmp_SDCR = (0x0 << 25) |  // MSDRAMEN
                (0x1 << 20);    // DDR2EN
        printf("\tUsing DDR2 settings\n");

        EMIFDDR_SDCR = tmp_SDCR | // Settings that change depending on DDR2 or MDDR
                (EMIFDDR_SDCR & 0xF0000000) |  // Reserved
                (0x0 << 27) |  // DDR2TERM1
                (0x0 << 26) |  // IBANK_POS
                (0x0 << 24) |  // DDRDRIVE1
                (0x0 << 23) |  // BOOTUNLOCK
                (0x0 << 22) |  // DDR2DDQS
                (0x0 << 21) |  // DDR2TERM0
                (0x0 << 19) |  // DDRDLL_DIS
                (0x0 << 18) |  // DDRDRIVE0
                (0x1 << 17) |  // DDREN
                (0x1 << 16) |  // SDRAMEN
                (0x1 << 15) |  // TIMUNLOCK
                (0x1 << 14) |  // NM
                (0x0 << 12) |  // Reserved
                (0x3 << 9) |  // CL
                (0x0 << 7) |  // Reserved
                (0x3 << 4) |  // IBANK
                (0x0 << 3) |  // Reserved
                (0x2 << 0);      // PAGESIZE

        EMIFDDR_SDCR2 = 0x00000000; // IBANK_POS set to 0 so this register does not apply

        if (DDR_DEBUG) {
            // Configure EMIF with max timings for more slack
            // Try this if memory is not stable

            EMIFDDR_SDTIMR1 = (0x7F << 25) |  // tRFC
                    (0x07 << 22) |  // tRP
                    (0x07 << 19) |  // tRCD
                    (0x07 << 16) |  // tWR
                    (0x1F << 11) |  // tRAS
                    (0x1F << 6) |  // tRC
                    (0x07 << 3) |  // tRRD
                    (EMIFDDR_SDTIMR1 & 0x4) |  // Reserved
                    (0x03 << 0);                // tWTR

            EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000) |  // Reserved
                    (((unsigned int) ((70000 / 3400) - 0.5)) << 27) | // tRASMAX (original 7812.5)
                    (0x3 << 25) |  // tXP
                    (0x0 << 23) |  // tODT (Not supported)
                    (0x7F << 16) |  // tXSNR
                    (0xFF << 8) |  // tXSRD
                    (0x07 << 5) |  // tRTP (1 Cycle)
                    (0x1F << 0);      // tCKE

            printf("\tDDR Timings Configured for Debug\n");
        } else {
            // Let float -> integer truncate handle minus 1; Safer to round up for timings
            EMIFDDR_SDTIMR1 = (19 << 25) |  // tRFC
                    (1 << 22) |  // tRP
                    (1 << 19) |  // tRCD
                    (2 << 16) |  // tWR
                    (5 << 11) |  // tRAS
                    (8 << 6) |  // tRC
                    (1 << 3) |  // tRRD
                    (0 << 2) |  // Reserved
                    (1 << 0);    // tWTR

            EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000) |  // Reserved
                    (8 << 27) |  // tRASMAX
                    (2 << 25) |  // tXP
                    (0 << 23) |  // tODT (Not supported)
                    (18 << 16) |  // tXSNR (tXSR for mDDR)
                    (199 << 8) |  // tXSRD (tXSR for mDDR)
                    (1 << 5) |  // tRTP
                    (2 << 0);     // tCKE
        }

        EMIFDDR_SDCR &= ~0x00008000; // Clear TIMUNLOCK

        // Let float -> integer truncate handle RR round-down; Safer to round down for refresh rate
        EMIFDDR_SDRCR = (0x1 << 31) | // LPMODEN (Required for LPSC SyncReset/Enable)
                (0x1 << 30) |  // MCLKSTOPEN (Required for LPSC SyncReset/Enable)
                (0x0 << 24) |  // Reserved
                (0x0 << 23) |  // SR_PD
                (0x0 << 16) |  // Reserved
                (0x260 << 0);     // RR

        // SyncReset the Clock to EMIFDDR SDRAM
        (这里给PSC_MDCTL赋值为0x1(SYNCRST),PSC_PTCMD赋值为0x1任然不会改变,读出PSC_PTSTAT为0x1,然后就一致停到循环里了)
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_DDR2_MDDR,
                PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_SYNCRST);
       
        // Enable the Clock to EMIFDDR SDRAM
        PSCModuleControl(SOC_PSC_1_REGS, HW_PSC_DDR2_MDDR,
                PSC_POWERDOMAIN_ALWAYS_ON, PSC_MDCTL_NEXT_ENABLE);
      
        // Disable self-refresh
        EMIFDDR_SDRCR &= ~0xC0000000;
      
        EMIFDDR_PBBPR = 0x0;
    }