How can I rotate just the input in PXP?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How can I rotate just the input in PXP?

Jump to solution
2,369 Views
steveschefterti
Contributor III

I am using an iMX6ULL.  The driver (drivers/dma/pxp/pxp_dma_v3.c) for PXP defaults to performing the rotation at the output when rotation is requested.  That is, it sets the ROTATE0 in PXP_CTRL instead of ROTATE1.  I wish to perform the rotation on just the input.  This is because I wish to use an alpha layer and don't want that rotated (just want PS rotated).

 

I have modified the driver to set ROTATE1 instead but the output is not correct.

 

In order to demonstrate the problem, I created a simple and small input buffer.  It is 16 x 16 pixels of 32 bits each (unpacked 24 bit RGB).  I set the red value to 0xFF and the green value to 0x00.  For the blue value, I set it to the row number so that I can see what PXP has done with the data during rotation:

Input:
========= 0x76fb7000 ==============
00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001
00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001 00ff0001
========= 0x76fb7040 ==============
00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002
00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002 00ff0002
========= 0x76fb7080 ==============
00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003
00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003 00ff0003
========= 0x76fb70c0 ==============
00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004
00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004 00ff0004

...

00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f
00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f 00ff000f
========= 0x76fb73c0 ==============
00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010
00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010 00ff0010

I ask for an output which is 32 x 32 pixels.  With the original rotation (ROTATE0, rotation at output) all appears normal:

 

Output:
========= 0x75b3e000 ==============
00ff0010 00ff0010 00ff000f 00ff000f 00ff000e 00ff000e 00ff000d 00ff000d
00ff000c 00ff000c 00ff000b 00ff000b 00ff000a 00ff000a 00ff0009 00ff0009
00ff0008 00ff0008 00ff0007 00ff0007 00ff0006 00ff0006 00ff0005 00ff0005
00ff0004 00ff0004 00ff0003 00ff0003 00ff0002 00ff0002 00ff0001 00ff0001
========= 0x75b3e080 ==============
00ff0010 00ff0010 00ff000f 00ff000f 00ff000e 00ff000e 00ff000d 00ff000d
00ff000c 00ff000c 00ff000b 00ff000b 00ff000a 00ff000a 00ff0009 00ff0009
00ff0008 00ff0008 00ff0007 00ff0007 00ff0006 00ff0006 00ff0005 00ff0005
00ff0004 00ff0004 00ff0003 00ff0003 00ff0002 00ff0002 00ff0001 00ff0001
========= 0x75b3e100 ==============
00ff0010 00ff0010 00ff000f 00ff000f 00ff000e 00ff000e 00ff000d 00ff000d
00ff000c 00ff000c 00ff000b 00ff000b 00ff000a 00ff000a 00ff0009 00ff0009
00ff0008 00ff0008 00ff0007 00ff0007 00ff0006 00ff0006 00ff0005 00ff0005
00ff0004 00ff0004 00ff0003 00ff0003 00ff0002 00ff0002 00ff0001 00ff0001
etc

So the image has been rotated and doubled in size as expected.

 

That is not the case with input rotation (ROTATE1) though

Output:
========= 0x75b3e000 ==============
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
========= 0x75b3e080 ==============
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
========= 0x75b3e100 ==============
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
etc


In this small 16x16 example, I'm seeing all zeros where the output data should be.  In a larger example, the output data is nonzero in places, but not at all like the input image.

 

The following are the PXP register dumps.

First, the case with rotation performed at the output:

PXP_CTRL 0x0f010103
PXP_STAT 0x04030001
PXP_OUT_CTRL 0x00000000
PXP_OUT_BUF 0x8dd00000
PXP_OUT_BUF2 0x00000000
PXP_OUT_PITCH 0x00000080
PXP_OUT_LRC 0x001f001f
PXP_OUT_PS_ULC 0x00000000
PXP_OUT_PS_LRC 0x001f001f
PXP_OUT_AS_ULC 0x3fff3fff
PXP_OUT_AS_LRC 0x00000000
PXP_PS_CTRL 0x00000004
PXP_PS_BUF 0x8d24d000
PXP_PS_UBUF 0x00000000
PXP_PS_VBUF 0x00000000
PXP_PS_PITCH 0x00000040 64
PXP_PS_BACKGROUND_0 0x00000000
PXP_PS_SCALE 0x07bd07bd
PXP_PS_OFFSET 0x00000000
PXP_PS_CLRKEYLOW_0 0xffffff
PXP_PS_CLRKEYHIGH 0x00000000
PXP_AS_CTRL 0x00000000
PXP_AS_BUF 0x00000000
PXP_AS_PITCH 0x00000000
PXP_AS_CLRKEYLOW 0x00ffffff
PXP_AS_CLRKEYHIGH 0x00000000
PXP_CSC1_COEF0 0x40000000
PXP_CSC1_COEF1 0x01230208
PXP_CSC1_COEF2 0x079b076c
PXP_CSC2_CTRL 0x00000001
PXP_CSC2_COEF0 0x00000000
PXP_CSC2_COEF1 0x00000000
PXP_CSC2_COEF2 0x00000000
PXP_CSC2_COEF3 0x00000000
PXP_CSC2_COEF4 0x00000000
PXP_CSC2_COEF5 0x00000000
PXP_LUT_CTRL 0x80010000
PXP_LUT_ADDR 0x00000000
PXP_LUT_DATA 0x00000000
PXP_LUT_EXTMEM 0x00000000
PXP_CFA 0x00000000
PXP_ALPHA_A_CTRL 0x00000000
PXP_ALPHA_B_CTRL 0x00000000
PXP_POWER_REG0 0x00000000
PXP_NEXT 0x00000000
PXP_DEBUGCTRL 0x00000000
PXP_DEBUG 0x00000000
PXP_VERSION 0x03000000

 

Next, with rotation performed on the input

PXP_CTRL 0x0f011003
PXP_STAT 0x00040001
PXP_OUT_CTRL 0x00000000
PXP_OUT_BUF 0x8d400000
PXP_OUT_BUF2 0x00000000
PXP_OUT_PITCH 0x00000080
PXP_OUT_LRC 0x001f001f
PXP_OUT_PS_ULC 0x00000000
PXP_OUT_PS_LRC 0x001f001f
PXP_OUT_AS_ULC 0x3fff3fff
PXP_OUT_AS_LRC 0x00000000
PXP_PS_CTRL 0x00000004
PXP_PS_BUF 0x8d1be000
PXP_PS_UBUF 0x00000000
PXP_PS_VBUF 0x00000000
PXP_PS_PITCH 0x00000040 64
PXP_PS_BACKGROUND_0 0x00000000
PXP_PS_SCALE 0x07bd07bd
PXP_PS_OFFSET 0x00000000
PXP_PS_CLRKEYLOW_0 0xffffff
PXP_PS_CLRKEYHIGH 0x00000000
PXP_AS_CTRL 0x00000000
PXP_AS_BUF 0x00000000
PXP_AS_PITCH 0x00000000
PXP_AS_CLRKEYLOW 0x00ffffff
PXP_AS_CLRKEYHIGH 0x00000000
PXP_CSC1_COEF0 0x40000000
PXP_CSC1_COEF1 0x01230208
PXP_CSC1_COEF2 0x079b076c
PXP_CSC2_CTRL 0x00000001
PXP_CSC2_COEF0 0x00000000
PXP_CSC2_COEF1 0x00000000
PXP_CSC2_COEF2 0x00000000
PXP_CSC2_COEF3 0x00000000
PXP_CSC2_COEF4 0x00000000
PXP_CSC2_COEF5 0x00000000
PXP_LUT_CTRL 0x80010000
PXP_LUT_ADDR 0x00000000
PXP_LUT_DATA 0x00000000
PXP_LUT_EXTMEM 0x00000000
PXP_CFA 0x00000000
PXP_ALPHA_A_CTRL 0x00000000
PXP_ALPHA_B_CTRL 0x00000000
PXP_POWER_REG0 0x00000000
PXP_NEXT 0x00000000
PXP_DEBUGCTRL 0x00000000
PXP_DEBUG 0x00000000
PXP_VERSION 0x0300000

 

Besides differences in virtual address, the difference is in PXP_CTRL:

PXP_CTRL   0x0f010103 -> 0x0f011003   (set ROTATE1 instead of ROTATE0)

So how can I rotate just the input (PS) and not output (soon to be PS + AS)?

Thanks,

    Steve

Tags (1)
0 Kudos
1 Solution
2,026 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello Steve,

Was found a bug on PXP IP from i.MX6ULL. The rotation block 2 can't perform rotation if resize or flip is also made. In these cases the image must be passed twice on PXP and perform one operation each time. If Rotation2 is enabled and rotation/flip are also made, the output will be a garbage.

The Linux driver will always switch to Rotation1 to make the rotation.

Regards

View solution in original post

9 Replies
2,027 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello Steve,

Was found a bug on PXP IP from i.MX6ULL. The rotation block 2 can't perform rotation if resize or flip is also made. In these cases the image must be passed twice on PXP and perform one operation each time. If Rotation2 is enabled and rotation/flip are also made, the output will be a garbage.

The Linux driver will always switch to Rotation1 to make the rotation.

Regards

2,026 Views
steveschefterti
Contributor III

Thanks for the information.

    Steve

0 Kudos
2,026 Views
steveschefterti
Contributor III

I received information from the 1039882 thread that I referenced.  Unfortunately, it didn't help.  It was about getting rotation working in the SDK.  Rotation is already working in Linux, just not at the location in the pipeline that I need it to.

Some more information:  The 6ULL RM shows the pipeline stages

PXP.jpg

I want to rotate at the stage circled in red.  It works when rotation is done at the stage circled in green.

The Linux driver always enables rotation at both locations (ENABLE_ROTATEn bits in PXP_HW_PXP_CTRLn) whether the image is to be rotated or not.  In order to have the image actually rotated, it sets the rotation angle to a non-zero value (ROTATE1 or ROTATE0 in PXP_HW_PXP_CTRLn) and sets the muxes (MUX3/MUX12) to transfer the rotated image down the pipeline.  In the non-rotate case, it sets the rotation angle to zero and sets the muxes to use the line that bypasses the rotation blocks.

I have found that anytime a non-zero value is used for ROTATE1 (corresponding to the circled Rotation 2 block), the output is all zeros.  That is the case even if MUX3 is set to ignore the output of the Rotation 2 block (use the output of CSC1 instead).

In terms of register settings, I leave PXP_HW_PXP_DATA_PATH_CTRL0n set to 0xDD7DFF3F (MUX3 selects CSC1).

PXP_HW_PXP_CTRLn = 0x0F010003 works

PXP_HW_PXP_CTRLn = 0x0F011003 fails

the difference being the rotation angle in the bypassed Rotation 2 block.

0 Kudos
2,026 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

It's difficult to test the Rotation 1 on current kernel driver because it selects the rotation block automaticaly and Rotation 1 is used only in very specific cases. I wasn't able to find a demo/example code that selects Rotatation 1.

 

I changed the kernel driver to force the usage of Rotation 1 and got the same result of the thread above.

 

In the register log from customer, the MUX3 register is not printed. Coul you tell us, to set MUX3 and print the register PXP_HW_PXP_DATA_PATH_CTRL0.

 

Regards

0 Kudos
2,026 Views
steveschefterti
Contributor III

I have not modified the MUX3 settings in the driver

PXP_WFE_B_STAGE1_MUX3, PXP_WFE_B_STAGE2_MUX3 and PXP_WFE_B_STAGE3_MUX3 are all 0.  HW_PXP_DATA_PATH_CTRL0 is 0xdc7dff3f

I understand from a separate conversation that this topic was discussed in https://community.nxp.com/message/1039882.  However, I do not have access to that thread.  Can you either enable access for me or tell me what changes were made to the MUX3 register for ROTATION1 operation?

Thanks,

     Steve

0 Kudos
2,026 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

Hello Steve,

I guess I saw this question before in the previously thread:

https://community.nxp.com/thread/434514 

Regards

0 Kudos
2,026 Views
steveschefterti
Contributor III

Hi.

That doesn't look like it addresses my question.  First, it's not clear from the response that the person used PXP to do the rotation at all.  They just talk about copying between buffers periodically with a "rotation calculation".

To be clear, getting the PXP to do rotation is not an issue.  That's supported in the Linux driver. 

However, there are two places where rotation can be performed by PXP.  One (default in the Linux driver) works.  One doesn't work.  I need to use the one that doesn't work so that only the input (PS) is rotation, not the output (which will include both PS and AS).  I expand on that more in my original question.

    Steve

0 Kudos
2,026 Views
Bio_TICFSL
NXP TechSupport
NXP TechSupport

You can check the kernel 4.14.98_2.0.0_ga:

https://source.codeaurora.org/external/imx/linux-imx/tree/drivers/dma/pxp/pxp_dma_v3.c?h=imx_4.14.98...

 

This release supports i.MX6ULL and has ROTATE0 implemented.

Regards

0 Kudos
2,026 Views
steveschefterti
Contributor III

ROTATE0 works in the kernel version that I'm using (4.14.78).  It is ROTATE1 that is the problem.

Also, other than adding case statements in support of PXP_PIX_FMT_VUY444, the PXP driver in 4.14.98 is the same as the one in 4.14.78.

       Steve

0 Kudos