diff options
Diffstat (limited to 'drivers/gpu/drm/vc4/vc4_hvs.c')
-rw-r--r-- | drivers/gpu/drm/vc4/vc4_hvs.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c index 024a2cdff5b2..27096e49c606 100644 --- a/drivers/gpu/drm/vc4/vc4_hvs.c +++ b/drivers/gpu/drm/vc4/vc4_hvs.c @@ -806,7 +806,7 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) struct vc4_hvs *hvs = NULL; int ret; u32 dispctrl; - u32 reg; + u32 reg, top; hvs = __vc4_hvs_alloc(vc4, NULL); if (IS_ERR(hvs)) @@ -915,6 +915,60 @@ static int vc4_hvs_bind(struct device *dev, struct device *master, void *data) HVS_WRITE(SCALER_DISPCTRL, dispctrl); + /* Recompute Composite Output Buffer (COB) allocations for the displays + */ + if (!vc4->is_vc5) { + /* The COB is 20736 pixels, or just over 10 lines at 2048 wide. + * The bottom 2048 pixels are full 32bpp RGBA (intended for the + * TXP composing RGBA to memory), whilst the remainder are only + * 24bpp RGB. + * + * Assign 3 lines to channels 1 & 2, and just over 4 lines to + * channel 0. + */ + #define VC4_COB_SIZE 20736 + #define VC4_COB_LINE_WIDTH 2048 + #define VC4_COB_NUM_LINES 3 + reg = 0; + top = VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE2, reg); + reg = top; + top += VC4_COB_LINE_WIDTH * VC4_COB_NUM_LINES; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE1, reg); + reg = top; + top = VC4_COB_SIZE; + reg |= (top - 1) << 16; + HVS_WRITE(SCALER_DISPBASE0, reg); + } else { + /* The COB is 44416 pixels, or 10.8 lines at 4096 wide. + * The bottom 4096 pixels are full RGBA (intended for the TXP + * composing RGBA to memory), whilst the remainder are only + * RGB. Addressing is always pixel wide. + * + * Assign 3 lines of 4096 to channels 1 & 2, and just over 4 + * lines. to channel 0. + */ + #define VC5_COB_SIZE 44416 + #define VC5_COB_LINE_WIDTH 4096 + #define VC5_COB_NUM_LINES 3 + reg = 0; + top = VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE2, reg); + top += 16; + reg = top; + top += VC5_COB_LINE_WIDTH * VC5_COB_NUM_LINES; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE1, reg); + top += 16; + reg = top; + top = VC5_COB_SIZE; + reg |= top << 16; + HVS_WRITE(SCALER_DISPBASE0, reg); + } + ret = devm_request_irq(dev, platform_get_irq(pdev, 0), vc4_hvs_irq_handler, 0, "vc4 hvs", drm); if (ret) |