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.

PLL regs Configuration on DM368

Hi!

We have dm368 custom board. We using dvsdk 4_02_00_06, boot linux from sd card.

I need to change VENC clock from 27Mhz to 29.5Mhz (in order to output digital video in square pixel mode(768x576))

So we calculated next configuration for PLL2:

PreDiv: 22

Mult: 622

Post: 1

I read SPRUFG5A, 6.5.2.2 Pre-Divider (PREDIV), PLL Multiplier (PLLM), and Post-Divider (POSTDIV), followed instruction and added regs configuration to davinci_enc_set_pal in davinci_platform.c

But when I boot linux, it hangs on

Uncompressing Linux.............................................................
.............................................................................. d
one, booting the kernel.

What may cause the problem?

  • Anton,

    It might be crashing some where in the beginning of display driver initialization. Since serial logs are not enabled you may not be seeing the logs. 

    Please try adding the following to the bootargs.

    earlyprintk debug ignore_loglevel log_buf_len=10M print_fatal_signals=1 LOGLEVEL=8

  • Renjith,

    Thanks for your reply

    Looks like when processor enters bypass mode, its freq too low and it hangs. I switch ARM clocks to PLL1. Clocks on PLL2 successfully changed.

    Now I think i should configure VENC to output 768x576 video and now I'm looking through manuals how to do it. Any hints? Thanks!

  • Anton,

    Originally were you using Standard mode(NTSC/PAL) or non-standard mode? You'll have to drive it in non-standard mode and you can configure the VENC to take the custom resolution, by configuring the VENC registers properly. Also you have to change the OSD registers as well to change the resolution.

  •     I accidentally deleted all my changes about pll config and now I can't repeat them. I'm doing everything like last time, but when it comes to polling LOCK bits, it appeared that they always are high. Here is the code, what am I doing wrong?

    //Changing ARM clock to PLL2
        printk("Starting PLL change \n");
        temp = __raw_readl(IO_ADDRESS(0x01C40048));
        printk("temp = %X", temp);
        temp &= ~(0x1 << 29);
        printk("temp = %X", temp);
        __raw_writel(temp, IO_ADDRESS(0x01C40048));
        printk("Changed\n");
        
        printk("Going to bypass\n");
        //going to bypass mode
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        printk("temp = %X\n", temp);
        temp &= ~(0x1);
        printk("temp = %X\n", temp);
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        udelay(4);
        //printk("Bypassed\n");
        //going to reset
        
        printk("Going to reser\n");
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        printk("temp = %X", temp);
        temp |= (0x1 << 3);
        printk("temp = %X", temp);
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        udelay(5);
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        printk("temp = %X\n", temp);
        temp &= ~(0x1 << 3);
        printk("temp = %X\n", temp);
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        printk("Reseted\n");
        
        //changing prediv, pllm
        //pllm
        
        __raw_writel(0x137, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x110));
        //prediv
        __raw_writel(0x8016, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x114));
        
        printk("Writeing seq\n");
        //writing seq
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        temp |= (0x1 << 16); //TINITZ = 1
        temp |= (0x1 << 18); //TENABLEDIV = 1
        temp |= (0x1 << 17); //TENABLE = 1
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        temp &= ~(0x1 << 16); //TINITZ = 0
        temp |= (0x1 << 18); //TENABLEDIV = 1
        temp |= (0x1 << 17); //TENABLE = 1
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        temp &= ~(0x1 << 16); //TINITZ = 0
        temp &= ~(0x1 << 18); //TENABLEDIV = 0
        temp &= ~(0x1 << 17); //TENABLE = 0
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        temp |= (0x1 << 16); //TINITZ = 1
        temp &= ~(0x1 << 18); //TENABLEDIV = 0
        temp &= ~(0x1 << 17); //TENABLE = 0
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x108));
        
        printk("Wroted seq\n");
        //checking GOSTAT bit
        unsigned int stat = 0;
        do
        {
        printk("Checking stat\n");
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x13C));
        printk("temp = %X\n", temp);
        stat = temp & 0x1;
        }
        while (stat);
        //changing pll_div
        //div1
        __raw_writel(0x801A, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x118));
        //div2
        __raw_writel(0x8001, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x11C));
        //div3
        __raw_writel(0x8001, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x120));
        //div4
        __raw_writel(0x801F, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x160));
        //div5
        __raw_writel(0x8015, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x164));
        
        //GO
        printk("GO!\n");
        __raw_writel(0x1, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x138));
        stat = 0;
        do
        {
        printk("checking stat\n");
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x13C));
        stat = temp & 0x1;
        printk("temp = %X\n", temp);
        }
        while (stat);
        printk("Go finished\n");
        //checking LOCK

        temp = __raw_readl(IO_ADDRESS(0x01C40088));
        printk("Temp = %X\n", temp);
        do
        {
            temp = __raw_readl(IO_ADDRESS(0x01C40088));
            stat = temp & (0b111 << 25);
            stat = stat >> 25;
        }
        while(stat == 0b111);
        
        
        //returning to normal mode
        temp = __raw_readl(IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        temp |= 0x1;
        __raw_writel(temp, IO_ADDRESS(PLL2_BASE_ADDRESS + 0x100));
        printk("Returned to normal mode\n");
        //changing arm
        temp = __raw_readl(IO_ADDRESS(0x01C40048));
        temp |= (0x1 << 29);
        __raw_writel(temp, IO_ADDRESS(0x01C40048));
        printk("Clocks changed\n");

  • Well, I ignored this LOCKs and everything configured fine!

  • Renjith,

    I'm using non-standard mode and  here is how I configure VENC_REGS(for 768x576 interlaced):

        dispc_reg_out(VENC_VIDCTL, 0x6000);
        dispc_reg_out(VENC_DCLKCTL, 0x005);
        dispc_reg_out(VENC_DCLKPTN0, 0x13);    
        dispc_reg_out(VENC_SYNCCTL, 0x400F);
        dispc_reg_out(VENC_VMOD, 0x1251);
        dispc_reg_out(VENC_YCCCTL, 0x1);
        dispc_reg_out(VENC_VDPRO, 0x100);
        dispc_reg_out(VENC_HINT, 0x75F);
        dispc_reg_out(VENC_HSTART, 0x15C);
        dispc_reg_out(VENC_HVALID, 0x600);    
        dispc_reg_out(VENC_VINT, 0x271);
        dispc_reg_out(VENC_VSTART, 0x18);
        dispc_reg_out(VENC_VVALID, 0x120);

    It doesn't work right. I've analyzed it with Logic Analyzer and found out that field bit in SAV/EAV code are always zero

  • Anton,

    Can you read back the registers that you've written using devmem2 tool and verify the values written? Also can you write the VENC_VMOD-> VENC enable at last?

  • Renjith,

    I solved problem back on Thursday. Problem was in vertical sync. All I have to do now is to properly config OSD, I hope there won't be much trouble with it. Here is how I configured VENC regs:

        dispc_reg_out(VENC_HINT, 0x75F);
        dispc_reg_out(VENC_HSTART, 0x15C);
        dispc_reg_out(VENC_HVALID, 0x600);
        dispc_reg_out(VENC_VINT, 624);
        dispc_reg_out(VENC_VSTART, 21);
        dispc_reg_out(VENC_VVALID, 289);       //probably, VVALID should be 288, but I hadn't enough time to check this
        dispc_reg_out(VENC_VSTARTA, 22);
        dispc_reg_out(VENC_VVALIDA, 288);   
        dispc_reg_out(VENC_LINECTL, 0x1800);

  • So I successfully configured OSD regs, but I've found another problem: there is a lot of EAV codes instead of blanking sequence 80 10 at the end of the line. What might cause this problem?