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
Solved! Go to Solution.
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
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
Thanks for the information.
Steve
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
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.
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
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
Hello Steve,
I guess I saw this question before in the previously thread:
https://community.nxp.com/thread/434514
Regards
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
You can check the kernel 4.14.98_2.0.0_ga:
This release supports i.MX6ULL and has ROTATE0 implemented.
Regards
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