drm/vc4: txp: Handle 40-bits DMA Addresses
authorMaxime Ripard <maxime@cerno.tech>
Fri, 14 Apr 2023 15:47:11 +0000 (17:47 +0200)
committerDom Cobley <popcornmix@gmail.com>
Mon, 19 Feb 2024 11:34:58 +0000 (11:34 +0000)
The BCM2712 MOP and MOPLET can handle addresses larger than 32bits
through an extra register. We can easily support it and make it
conditional based on the compatible through a boolean in our variant
structure.

Signed-off-by: Maxime Ripard <maxime@cerno.tech>
drivers/gpu/drm/vc4/vc4_drv.h
drivers/gpu/drm/vc4/vc4_txp.c

index 7a78593..3596c01 100644 (file)
@@ -550,6 +550,7 @@ struct vc4_txp_data {
        struct vc4_crtc_data    base;
        unsigned int has_byte_enable:1;
        unsigned int size_minus_one:1;
+       unsigned int supports_40bit_addresses:1;
 };
 
 extern const struct vc4_txp_data bcm2835_txp_data;
index d2ee872..1858947 100644 (file)
 /* Number of lines received and committed to memory. */
 #define TXP_PROGRESS           0x10
 
+#define TXP_DST_PTR_HIGH       0x1c
+
 #define TXP_READ(offset)                                                               \
        ({                                                                              \
                kunit_fail_current_test("Accessing a register in a unit test!\n");      \
@@ -293,6 +295,7 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
        struct drm_framebuffer *fb;
        unsigned int hdisplay;
        unsigned int vdisplay;
+       dma_addr_t addr;
        u32 ctrl;
        int idx;
        int i;
@@ -330,7 +333,12 @@ static void vc4_txp_connector_atomic_commit(struct drm_connector *conn,
                return;
 
        gem = drm_fb_dma_get_gem_obj(fb, 0);
-       TXP_WRITE(TXP_DST_PTR, gem->dma_addr + fb->offsets[0]);
+       addr = gem->dma_addr + fb->offsets[0];
+       TXP_WRITE(TXP_DST_PTR, lower_32_bits(addr));
+
+       if (txp_data->supports_40bit_addresses)
+               TXP_WRITE(TXP_DST_PTR_HIGH, upper_32_bits(addr) & 0xff);
+
        TXP_WRITE(TXP_DST_PITCH, fb->pitches[0]);
 
        hdisplay = mode->hdisplay ?: 1;