GC300 2D unit won't work with GC2000 3D disabled on MMP3

Lubomir Rintel lkundrak at v3.sk
Mon Nov 30 17:07:45 UTC 2020


Hello,

(adding Ivan to Cc, since he brought the issue up privately. Ivan,
etnaviv@ is a moderated list, please subscribe if you're going to
reply.)

I'm wondering if anyone can help me understand what is going with Vivante
GC300 on a MMP3 and find a reasonable fix. MMP3 has these two GPU cores:

  [    2.142545] etnaviv-gpu d420d000.gpu: model: GC2000, revision: 5026
  [    2.154468] etnaviv-gpu d420f000.gpu: model: GC300, revision: 4634
  [    2.166808] [drm] Initialized etnaviv 1.3.0 20151214 for etnaviv on minor 0

Currently, clients that try to use the GC300 2D unit -- libdrm's etnaviv_2d
test or the xorg-x11-drv-armada ddx on a MMP3 don't work and etnaviv
complains:

  [  295.077770] etnaviv-gpu d420d000.gpu: recover hung GPU!

That is, until the clock that's supposedly for the GC2000 3D unit are
turned on. Then things work fine.

There's no documentation for the MMP3, but it is known that the relevant
register (at 0xd42828cc) in the APMU that controls the GPU clock looks
somewhat like this (on the right is the name of the clock that sets given
bits):

    28   24   20   16    12    8    4    0
  0011 0011 0001 1100  0000 0111 0000 1010 - 0x331c070a won't work
  0011 0011 0001 1100  0000 0111 0000 1111 - 0x331c070f works
  `--| `--|    | ||      `|  `|| `|`| |||`-- GC3D_AXI_RST_N      (1u << 0) ------------ gpu_3d_clk
     |    |    | ||       |   ||  | | ||`--- GC2D3D_RST_N        (1u << 1)    / --\
     |    |    | ||       |   ||  | | |`---- GC3D_AXICLK_EN      (1u << 2) --/     \
     |    |    | ||       |   ||  | | `----- GC2D3D_CLK_EN       (1u << 3)      ------- gpu_bus_clk
     |    |    | ||       |   ||  | |
     |    |    | ||       |   ||  | `------- GC3D_ACLK_SEL(n)    ((n & 3) << 4) ------- gpu_bus_mux
     |    |    | ||       |   ||  `--------- GC3D_CLK_SRC_SEL(n) ((n & 3) << 6) ------- gpu_3d_mux
     |    |    | ||       |   ||
     |    |    | ||       |   |`------------ GC_ISB              (1u << 8)
     |    |    | ||       |   `------------- GC_PWRUP(n)         ((n & 3) << 9) ------- gpu_power
     |    |    | ||       |
     |    |    | ||       `----------------- GC2D_CLK_SRC_SEL(n) ((n & 3) << 12) ------ gpu_2d_mux
     |    |    | ||
     |    |    | |`------------------------- GC2D_AXI_RST_N      (1u << 18) ---\
     |    |    | `-------------------------- GC2D_AXICLK_EN      (1u << 19) ----\
     |    |    |                                                                 >----- gpu_2d_clk
     |    |    `---------------------------- GC2D_CLK_EN         (1u << 20) ----/
     |    |
     |    `--------------------------------- GC3D_CLK_DIV(n)     ((n & 0xF) << 24) ---- gpu_3d_div
     |
     `-------------------------------------- GC2D_CLK_DIV(n)     ((n & 0xF) << 28) ---- gpu_2d_div

The bits that make a difference are the bits 0 and 2. Bit 0 is the inverse
reset and bit 2 is the clock enable. Both ought to be controlling the 3D
block which is why I find it odd that they're required for 2D to function.

To deal with the situation, I guess I could assume the bits don't do what
they say on the tin and make the clock driver set the "3d" bits for
both blocks. Alternatively, etnaviv could perhaps be made to enable the
3d clock when the 2d block is being used, perhaps configurable with a knob
in the DT.

Unfortunatelly, both options seem to suck. Perhaps someone with more clue
about how galcore are integrated into the socs might have a better idea?

Thanks
Lubo


More information about the etnaviv mailing list