diff options
20 files changed, 1230 insertions, 554 deletions
diff --git a/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml b/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml new file mode 100644 index 000000000000..e552d01b52b9 --- /dev/null +++ b/Documentation/devicetree/bindings/display/panel/wl-355608-a8.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/panel/wl-355608-a8.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: WL-355608-A8 3.5" (640x480 pixels) 24-bit IPS LCD panel + +maintainers: + - Ryan Walklin <ryan@testtoast.com> + +allOf: + - $ref: panel-common.yaml# + - $ref: /schemas/spi/spi-peripheral-props.yaml# + +properties: + compatible: + const: wl-355608-a8 + + reg: + maxItems: 1 + + spi-3wire: true + +required: + - compatible + - reg + - port + - power-supply + - reset-gpios + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + spi { + #address-cells = <1>; + #size-cells = <0>; + + panel@0 { + compatible = "wl-355608-a8"; + reg = <0>; + + spi-3wire; + spi-max-frequency = <3125000>; + + reset-gpios = <&pio 8 14 GPIO_ACTIVE_LOW>; // PI14 + + backlight = <&backlight>; + power-supply = <®_lcd>; + + port { + endpoint { + remote-endpoint = <&tcon_lcd0_out_lcd>; + }; + }; + }; + }; diff --git a/MAINTAINERS b/MAINTAINERS index b333782bdd83..6a1660480782 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7566,7 +7566,6 @@ F: include/drm/gpu_scheduler.h DRM PANEL DRIVERS M: Neil Armstrong <neil.armstrong@linaro.org> R: Jessica Zhang <quic_jesszhan@quicinc.com> -R: Sam Ravnborg <sam@ravnborg.org> L: dri-devel@lists.freedesktop.org S: Maintained T: git https://gitlab.freedesktop.org/drm/misc/kernel.git diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 84ae708fafe7..2298ca5e112e 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -50,8 +50,8 @@ static struct class *dma_heap_class; static DEFINE_XARRAY_ALLOC(dma_heap_minors); static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, - unsigned int fd_flags, - unsigned int heap_flags) + u32 fd_flags, + u64 heap_flags) { struct dma_buf *dmabuf; int fd; diff --git a/drivers/dma-buf/dma-resv.c b/drivers/dma-buf/dma-resv.c index e2869fb31140..5f8d010516f0 100644 --- a/drivers/dma-buf/dma-resv.c +++ b/drivers/dma-buf/dma-resv.c @@ -186,6 +186,13 @@ int dma_resv_reserve_fences(struct dma_resv *obj, unsigned int num_fences) dma_resv_assert_held(obj); + /* Driver and component code should never call this function with + * num_fences=0. If they do it usually points to bugs when calculating + * the number of needed fences dynamically. + */ + if (WARN_ON(!num_fences)) + return -EINVAL; + old = dma_resv_fences_list(obj); if (old && old->max_fences) { if ((old->num_fences + num_fences) <= old->max_fences) diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c index cc5cf4c2faf7..0f7ffb3ced20 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c @@ -30,10 +30,12 @@ * * @base: base CRTC state * @output_mode: RGBXXX output mode + * @dpi: output DPI mode */ struct atmel_hlcdc_crtc_state { struct drm_crtc_state base; unsigned int output_mode; + u8 dpi; }; static inline struct atmel_hlcdc_crtc_state * @@ -164,18 +166,24 @@ static void atmel_hlcdc_crtc_mode_set_nofb(struct drm_crtc *c) state = drm_crtc_state_to_atmel_hlcdc_crtc_state(c->state); cfg = state->output_mode << 8; - if (adj->flags & DRM_MODE_FLAG_NVSYNC) - cfg |= ATMEL_HLCDC_VSPOL; + if (!crtc->dc->desc->is_xlcdc) { + if (adj->flags & DRM_MODE_FLAG_NVSYNC) + cfg |= ATMEL_HLCDC_VSPOL; - if (adj->flags & DRM_MODE_FLAG_NHSYNC) - cfg |= ATMEL_HLCDC_HSPOL; + if (adj->flags & DRM_MODE_FLAG_NHSYNC) + cfg |= ATMEL_HLCDC_HSPOL; + } else { + cfg |= state->dpi << 11; + } regmap_update_bits(regmap, ATMEL_HLCDC_CFG(5), ATMEL_HLCDC_HSPOL | ATMEL_HLCDC_VSPOL | ATMEL_HLCDC_VSPDLYS | ATMEL_HLCDC_VSPDLYE | ATMEL_HLCDC_DISPPOL | ATMEL_HLCDC_DISPDLY | ATMEL_HLCDC_VSPSU | ATMEL_HLCDC_VSPHO | - ATMEL_HLCDC_GUARDTIME_MASK | ATMEL_HLCDC_MODE_MASK, + ATMEL_HLCDC_GUARDTIME_MASK | + (crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_MODE_MASK | + ATMEL_XLCDC_DPI : ATMEL_HLCDC_MODE_MASK), cfg); clk_disable_unprepare(crtc->dc->hlcdc->sys_clk); @@ -202,20 +210,37 @@ static void atmel_hlcdc_crtc_atomic_disable(struct drm_crtc *c, pm_runtime_get_sync(dev->dev); + if (crtc->dc->desc->is_xlcdc) { + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_CM); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + !(status & ATMEL_XLCDC_CM), + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n"); + + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_XLCDC_SD); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + status & ATMEL_XLCDC_SD, + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n"); + } + regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_DISP); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - (status & ATMEL_HLCDC_DISP)) - cpu_relax(); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + !(status & ATMEL_HLCDC_DISP), + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n"); regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_SYNC); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - (status & ATMEL_HLCDC_SYNC)) - cpu_relax(); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + !(status & ATMEL_HLCDC_SYNC), + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n"); regmap_write(regmap, ATMEL_HLCDC_DIS, ATMEL_HLCDC_PIXEL_CLK); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - (status & ATMEL_HLCDC_PIXEL_CLK)) - cpu_relax(); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + !(status & ATMEL_HLCDC_PIXEL_CLK), + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n"); clk_disable_unprepare(crtc->dc->hlcdc->sys_clk); pinctrl_pm_select_sleep_state(dev->dev); @@ -241,30 +266,95 @@ static void atmel_hlcdc_crtc_atomic_enable(struct drm_crtc *c, clk_prepare_enable(crtc->dc->hlcdc->sys_clk); regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_PIXEL_CLK); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - !(status & ATMEL_HLCDC_PIXEL_CLK)) - cpu_relax(); - + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + status & ATMEL_HLCDC_PIXEL_CLK, + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register CLKSTS timeout\n"); regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_SYNC); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - !(status & ATMEL_HLCDC_SYNC)) - cpu_relax(); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + status & ATMEL_HLCDC_SYNC, + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register LCDSTS timeout\n"); regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_HLCDC_DISP); - while (!regmap_read(regmap, ATMEL_HLCDC_SR, &status) && - !(status & ATMEL_HLCDC_DISP)) - cpu_relax(); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + status & ATMEL_HLCDC_DISP, + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register DISPSTS timeout\n"); + + if (crtc->dc->desc->is_xlcdc) { + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_CM); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + status & ATMEL_XLCDC_CM, + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register CMSTS timeout\n"); + + regmap_write(regmap, ATMEL_HLCDC_EN, ATMEL_XLCDC_SD); + if (regmap_read_poll_timeout(regmap, ATMEL_HLCDC_SR, status, + !(status & ATMEL_XLCDC_SD), + 10, 1000)) + dev_warn(dev->dev, "Atmel LCDC status register SDSTS timeout\n"); + } pm_runtime_put_sync(dev->dev); } -#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0) -#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1) -#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2) -#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3) -#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0) +#define ATMEL_HLCDC_RGB444_OUTPUT BIT(0) +#define ATMEL_HLCDC_RGB565_OUTPUT BIT(1) +#define ATMEL_HLCDC_RGB666_OUTPUT BIT(2) +#define ATMEL_HLCDC_RGB888_OUTPUT BIT(3) +#define ATMEL_HLCDC_DPI_RGB565C1_OUTPUT BIT(4) +#define ATMEL_HLCDC_DPI_RGB565C2_OUTPUT BIT(5) +#define ATMEL_HLCDC_DPI_RGB565C3_OUTPUT BIT(6) +#define ATMEL_HLCDC_DPI_RGB666C1_OUTPUT BIT(7) +#define ATMEL_HLCDC_DPI_RGB666C2_OUTPUT BIT(8) +#define ATMEL_HLCDC_DPI_RGB888_OUTPUT BIT(9) +#define ATMEL_HLCDC_OUTPUT_MODE_MASK GENMASK(3, 0) +#define ATMEL_XLCDC_OUTPUT_MODE_MASK GENMASK(9, 0) + +static int atmel_xlcdc_connector_output_dsi(struct drm_encoder *encoder, + struct drm_display_info *info) +{ + int j; + unsigned int supported_fmts = 0; + + switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) { + case 0: + break; + case MEDIA_BUS_FMT_RGB565_1X16: + return ATMEL_HLCDC_DPI_RGB565C1_OUTPUT; + case MEDIA_BUS_FMT_RGB666_1X18: + return ATMEL_HLCDC_DPI_RGB666C1_OUTPUT; + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + return ATMEL_HLCDC_DPI_RGB666C2_OUTPUT; + case MEDIA_BUS_FMT_RGB888_1X24: + return ATMEL_HLCDC_DPI_RGB888_OUTPUT; + default: + return -EINVAL; + } + + for (j = 0; j < info->num_bus_formats; j++) { + switch (info->bus_formats[j]) { + case MEDIA_BUS_FMT_RGB565_1X16: + supported_fmts |= ATMEL_HLCDC_DPI_RGB565C1_OUTPUT; + break; + case MEDIA_BUS_FMT_RGB666_1X18: + supported_fmts |= ATMEL_HLCDC_DPI_RGB666C1_OUTPUT; + break; + case MEDIA_BUS_FMT_RGB666_1X24_CPADHI: + supported_fmts |= ATMEL_HLCDC_DPI_RGB666C2_OUTPUT; + break; + case MEDIA_BUS_FMT_RGB888_1X24: + supported_fmts |= ATMEL_HLCDC_DPI_RGB888_OUTPUT; + break; + default: + break; + } + } + return supported_fmts; +} static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state) { @@ -277,6 +367,13 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state) encoder = state->best_encoder; if (!encoder) encoder = connector->encoder; + /* + * atmel-hlcdc to support DSI formats with DSI video pipeline + * when DRM_MODE_ENCODER_DSI type is set by + * connector driver component. + */ + if (encoder->encoder_type == DRM_MODE_ENCODER_DSI) + return atmel_xlcdc_connector_output_dsi(encoder, info); switch (atmel_hlcdc_encoder_get_bus_fmt(encoder)) { case 0: @@ -317,7 +414,7 @@ static int atmel_hlcdc_connector_output_mode(struct drm_connector_state *state) static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state) { - unsigned int output_fmts = ATMEL_HLCDC_OUTPUT_MODE_MASK; + unsigned int output_fmts; struct atmel_hlcdc_crtc_state *hstate; struct drm_connector_state *cstate; struct drm_connector *connector; @@ -325,6 +422,8 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state) int i; crtc = drm_crtc_to_atmel_hlcdc_crtc(state->crtc); + output_fmts = crtc->dc->desc->is_xlcdc ? ATMEL_XLCDC_OUTPUT_MODE_MASK : + ATMEL_HLCDC_OUTPUT_MODE_MASK; for_each_new_connector_in_state(state->state, connector, cstate, i) { unsigned int supported_fmts = 0; @@ -345,7 +444,15 @@ static int atmel_hlcdc_crtc_select_output_mode(struct drm_crtc_state *state) hstate = drm_crtc_state_to_atmel_hlcdc_crtc_state(state); hstate->output_mode = fls(output_fmts) - 1; - + if (crtc->dc->desc->is_xlcdc) { + /* check if MIPI DPI bit needs to be set */ + if (fls(output_fmts) > 3) { + hstate->output_mode -= 4; + hstate->dpi = 1; + } else { + hstate->dpi = 0; + } + } return 0; } @@ -449,6 +556,7 @@ static struct drm_crtc_state * atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) { struct atmel_hlcdc_crtc_state *state, *cur; + struct atmel_hlcdc_crtc *c = drm_crtc_to_atmel_hlcdc_crtc(crtc); if (WARN_ON(!crtc->state)) return NULL; @@ -460,6 +568,8 @@ atmel_hlcdc_crtc_duplicate_state(struct drm_crtc *crtc) cur = drm_crtc_state_to_atmel_hlcdc_crtc_state(crtc->state); state->output_mode = cur->output_mode; + if (c->dc->desc->is_xlcdc) + state->dpi = cur->dpi; return &state->base; } diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c index 84c54e8622d1..9ce429f889ca 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c @@ -58,6 +58,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9n12 = { .conflicting_output_formats = true, .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9n12_layers), .layers = atmel_hlcdc_at91sam9n12_layers, + .ops = &atmel_hlcdc_ops, }; static const struct atmel_hlcdc_layer_desc atmel_hlcdc_at91sam9x5_layers[] = { @@ -151,6 +152,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_at91sam9x5 = { .conflicting_output_formats = true, .nlayers = ARRAY_SIZE(atmel_hlcdc_at91sam9x5_layers), .layers = atmel_hlcdc_at91sam9x5_layers, + .ops = &atmel_hlcdc_ops, }; static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d3_layers[] = { @@ -269,6 +271,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d3 = { .conflicting_output_formats = true, .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d3_layers), .layers = atmel_hlcdc_sama5d3_layers, + .ops = &atmel_hlcdc_ops, }; static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sama5d4_layers[] = { @@ -364,6 +367,7 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sama5d4 = { .max_hpw = 0x3ff, .nlayers = ARRAY_SIZE(atmel_hlcdc_sama5d4_layers), .layers = atmel_hlcdc_sama5d4_layers, + .ops = &atmel_hlcdc_ops, }; static const struct atmel_hlcdc_layer_desc atmel_hlcdc_sam9x60_layers[] = { @@ -460,6 +464,103 @@ static const struct atmel_hlcdc_dc_desc atmel_hlcdc_dc_sam9x60 = { .fixed_clksrc = true, .nlayers = ARRAY_SIZE(atmel_hlcdc_sam9x60_layers), .layers = atmel_hlcdc_sam9x60_layers, + .ops = &atmel_hlcdc_ops, +}; + +static const struct atmel_hlcdc_layer_desc atmel_xlcdc_sam9x75_layers[] = { + { + .name = "base", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x60, + .id = 0, + .type = ATMEL_HLCDC_BASE_LAYER, + .cfgs_offset = 0x1c, + .layout = { + .xstride = { 2 }, + .default_color = 3, + .general_config = 4, + .disc_pos = 5, + .disc_size = 6, + }, + .clut_offset = 0x700, + }, + { + .name = "overlay1", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x160, + .id = 1, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .cfgs_offset = 0x1c, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + .clut_offset = 0xb00, + }, + { + .name = "overlay2", + .formats = &atmel_hlcdc_plane_rgb_formats, + .regs_offset = 0x260, + .id = 2, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .cfgs_offset = 0x1c, + .layout = { + .pos = 2, + .size = 3, + .xstride = { 4 }, + .pstride = { 5 }, + .default_color = 6, + .chroma_key = 7, + .chroma_key_mask = 8, + .general_config = 9, + }, + .clut_offset = 0xf00, + }, + { + .name = "high-end-overlay", + .formats = &atmel_hlcdc_plane_rgb_and_yuv_formats, + .regs_offset = 0x360, + .id = 3, + .type = ATMEL_HLCDC_OVERLAY_LAYER, + .cfgs_offset = 0x30, + .layout = { + .pos = 2, + .size = 3, + .memsize = 4, + .xstride = { 5, 7 }, + .pstride = { 6, 8 }, + .default_color = 9, + .chroma_key = 10, + .chroma_key_mask = 11, + .general_config = 12, + .csc = 16, + .scaler_config = 23, + .vxs_config = 30, + .hxs_config = 31, + }, + .clut_offset = 0x1300, + }, +}; + +static const struct atmel_hlcdc_dc_desc atmel_xlcdc_dc_sam9x75 = { + .min_width = 0, + .min_height = 0, + .max_width = 2048, + .max_height = 2048, + .max_spw = 0x3ff, + .max_vpw = 0x3ff, + .max_hpw = 0x3ff, + .fixed_clksrc = true, + .is_xlcdc = true, + .nlayers = ARRAY_SIZE(atmel_xlcdc_sam9x75_layers), + .layers = atmel_xlcdc_sam9x75_layers, + .ops = &atmel_xlcdc_ops, }; static const struct of_device_id atmel_hlcdc_of_match[] = { @@ -487,6 +588,10 @@ static const struct of_device_id atmel_hlcdc_of_match[] = { .compatible = "microchip,sam9x60-hlcdc", .data = &atmel_hlcdc_dc_sam9x60, }, + { + .compatible = "microchip,sam9x75-xlcdc", + .data = &atmel_xlcdc_dc_sam9x75, + }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, atmel_hlcdc_of_match); diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h index 5b5c774e0edf..e1a0bb24b511 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.h @@ -15,6 +15,7 @@ #include <drm/drm_plane.h> +/* LCD controller common registers */ #define ATMEL_HLCDC_LAYER_CHER 0x0 #define ATMEL_HLCDC_LAYER_CHDR 0x4 #define ATMEL_HLCDC_LAYER_CHSR 0x8 @@ -128,6 +129,47 @@ #define ATMEL_HLCDC_MAX_LAYERS 6 +/* XLCDC controller specific registers */ +#define ATMEL_XLCDC_LAYER_ENR 0x10 +#define ATMEL_XLCDC_LAYER_EN BIT(0) + +#define ATMEL_XLCDC_LAYER_IER 0x0 +#define ATMEL_XLCDC_LAYER_IDR 0x4 +#define ATMEL_XLCDC_LAYER_ISR 0xc +#define ATMEL_XLCDC_LAYER_OVR_IRQ(p) BIT(2 + (8 * (p))) + +#define ATMEL_XLCDC_LAYER_PLANE_ADDR(p) (((p) * 0x4) + 0x18) + +#define ATMEL_XLCDC_LAYER_DMA_CFG 0 + +#define ATMEL_XLCDC_LAYER_DMA BIT(0) +#define ATMEL_XLCDC_LAYER_REP BIT(1) +#define ATMEL_XLCDC_LAYER_DISCEN BIT(4) + +#define ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS (4 << 6) +#define ATMEL_XLCDC_LAYER_SFACTA_ONE BIT(9) +#define ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS (6 << 11) +#define ATMEL_XLCDC_LAYER_DFACTA_ONE BIT(14) + +#define ATMEL_XLCDC_LAYER_A0_SHIFT 16 +#define ATMEL_XLCDC_LAYER_A0(x) \ + ((x) << ATMEL_XLCDC_LAYER_A0_SHIFT) + +#define ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE BIT(0) +#define ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE BIT(1) +#define ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE BIT(5) + +#define ATMEL_XLCDC_LAYER_VXSYCFG_ONE BIT(0) +#define ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_VXSCCFG_ONE BIT(16) +#define ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE BIT(20) + +#define ATMEL_XLCDC_LAYER_HXSYCFG_ONE BIT(0) +#define ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE BIT(4) +#define ATMEL_XLCDC_LAYER_HXSCCFG_ONE BIT(16) +#define ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE BIT(20) + /** * Atmel HLCDC Layer registers layout structure * @@ -156,6 +198,8 @@ * @disc_pos: discard area position register * @disc_size: discard area size register * @csc: color space conversion register + * @vxs_config: vertical scalar filter taps control register + * @hxs_config: horizontal scalar filter taps control register */ struct atmel_hlcdc_layer_cfg_layout { int xstride[ATMEL_HLCDC_LAYER_MAX_PLANES]; @@ -175,6 +219,8 @@ struct atmel_hlcdc_layer_cfg_layout { int disc_pos; int disc_size; int csc; + int vxs_config; + int hxs_config; }; /** @@ -289,6 +335,64 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer) } /** + * struct atmel_hlcdc_dc - Atmel HLCDC Display Controller. + * @desc: HLCDC Display Controller description + * @dscrpool: DMA coherent pool used to allocate DMA descriptors + * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device + * @crtc: CRTC provided by the display controller + * @layers: active HLCDC layers + * @suspend: used to store the HLCDC state when entering suspend + * @suspend.imr: used to read/write LCDC Interrupt Mask Register + * @suspend.state: Atomic commit structure + */ +struct atmel_hlcdc_dc { + const struct atmel_hlcdc_dc_desc *desc; + struct dma_pool *dscrpool; + struct atmel_hlcdc *hlcdc; + struct drm_crtc *crtc; + struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS]; + struct { + u32 imr; + struct drm_atomic_state *state; + } suspend; +}; + +struct atmel_hlcdc_plane_state; + +/** + * struct atmel_lcdc_dc_ops - describes atmel_lcdc ops group + * to differentiate HLCDC and XLCDC IP code support + * @plane_setup_scaler: update the vertical and horizontal scaling factors + * @update_lcdc_buffers: update the each LCDC layers DMA registers + * @lcdc_atomic_disable: disable LCDC interrupts and layers + * @lcdc_update_general_settings: update each LCDC layers general + * configuration register + * @lcdc_atomic_update: enable the LCDC layers and interrupts + * @lcdc_csc_init: update the color space conversion co-efficient of + * High-end overlay register + * @lcdc_irq_dbg: to raise alert incase of interrupt overrun in any LCDC layer + */ +struct atmel_lcdc_dc_ops { + void (*plane_setup_scaler)(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state); + void (*lcdc_update_buffers)(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state, + u32 sr, int i); + void (*lcdc_atomic_disable)(struct atmel_hlcdc_plane *plane); + void (*lcdc_update_general_settings)(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state); + void (*lcdc_atomic_update)(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_dc *dc); + void (*lcdc_csc_init)(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc); + void (*lcdc_irq_dbg)(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc); +}; + +extern const struct atmel_lcdc_dc_ops atmel_hlcdc_ops; +extern const struct atmel_lcdc_dc_ops atmel_xlcdc_ops; + +/** * Atmel HLCDC Display Controller description structure. * * This structure describes the HLCDC IP capabilities and depends on the @@ -304,8 +408,10 @@ atmel_hlcdc_layer_to_plane(struct atmel_hlcdc_layer *layer) * @conflicting_output_formats: true if RGBXXX output formats conflict with * each other. * @fixed_clksrc: true if clock source is fixed + * @is_xlcdc: true if XLCDC IP is supported * @layers: a layer description table describing available layers * @nlayers: layer description table size + * @ops: atmel lcdc dc ops */ struct atmel_hlcdc_dc_desc { int min_width; @@ -317,32 +423,10 @@ struct atmel_hlcdc_dc_desc { int max_hpw; bool conflicting_output_formats; bool fixed_clksrc; + bool is_xlcdc; const struct atmel_hlcdc_layer_desc *layers; int nlayers; -}; - -/** - * Atmel HLCDC Display Controller. - * - * @desc: HLCDC Display Controller description - * @dscrpool: DMA coherent pool used to allocate DMA descriptors - * @hlcdc: pointer to the atmel_hlcdc structure provided by the MFD device - * @fbdev: framebuffer device attached to the Display Controller - * @crtc: CRTC provided by the display controller - * @planes: instantiated planes - * @layers: active HLCDC layers - * @suspend: used to store the HLCDC state when entering suspend - */ -struct atmel_hlcdc_dc { - const struct atmel_hlcdc_dc_desc *desc; - struct dma_pool *dscrpool; - struct atmel_hlcdc *hlcdc; - struct drm_crtc *crtc; - struct atmel_hlcdc_layer *layers[ATMEL_HLCDC_MAX_LAYERS]; - struct { - u32 imr; - struct drm_atomic_state *state; - } suspend; + const struct atmel_lcdc_dc_ops *ops; }; extern struct atmel_hlcdc_formats atmel_hlcdc_plane_rgb_formats; diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c index daa508504f47..4a7ba0918eca 100644 --- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c @@ -282,8 +282,9 @@ atmel_hlcdc_plane_scaler_set_phicoeff(struct atmel_hlcdc_plane *plane, coeff_tab[i]); } -static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, - struct atmel_hlcdc_plane_state *state) +static +void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state) { const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; u32 xfactor, yfactor; @@ -330,11 +331,61 @@ static void atmel_hlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, yfactor)); } +static +void atmel_xlcdc_plane_setup_scaler(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state) +{ + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + u32 xfactor, yfactor; + + if (!desc->layout.scaler_config) + return; + + if (state->crtc_w == state->src_w && state->crtc_h == state->src_h) { + atmel_hlcdc_layer_write_cfg(&plane->layer, + desc->layout.scaler_config, 0); + return; + } + + /* xfactor = round[(2^20 * XMEMSIZE)/XSIZE)] */ + xfactor = (u32)(((1 << 20) * state->src_w) / state->crtc_w); + + /* yfactor = round[(2^20 * YMEMSIZE)/YSIZE)] */ + yfactor = (u32)(((1 << 20) * state->src_h) / state->crtc_h); + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config, + ATMEL_XLCDC_LAYER_VSCALER_LUMA_ENABLE | + ATMEL_XLCDC_LAYER_VSCALER_CHROMA_ENABLE | + ATMEL_XLCDC_LAYER_HSCALER_LUMA_ENABLE | + ATMEL_XLCDC_LAYER_HSCALER_CHROMA_ENABLE); + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 1, + yfactor); + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 3, + xfactor); + + /* + * With YCbCr 4:2:2 and YCbYcr 4:2:0 window resampling, configuration + * register LCDC_HEOCFG25.VXSCFACT and LCDC_HEOCFG27.HXSCFACT is half + * the value of yfactor and xfactor. + */ + if (state->base.fb->format->format == DRM_FORMAT_YUV420) { + yfactor /= 2; + xfactor /= 2; + } + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 2, + yfactor); + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.scaler_config + 4, + xfactor); +} + static void atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane, struct atmel_hlcdc_plane_state *state) { const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private; if (desc->layout.size) atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.size, @@ -352,12 +403,12 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane, ATMEL_HLCDC_LAYER_POS(state->crtc_x, state->crtc_y)); - atmel_hlcdc_plane_setup_scaler(plane, state); + dc->desc->ops->plane_setup_scaler(plane, state); } -static void -atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, - struct atmel_hlcdc_plane_state *state) +static +void atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state) { unsigned int cfg = ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id; const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; @@ -393,6 +444,40 @@ atmel_hlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, cfg); } +static +void atmel_xlcdc_plane_update_general_settings(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state) +{ + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + const struct drm_format_info *format = state->base.fb->format; + unsigned int cfg; + + atmel_hlcdc_layer_write_cfg(&plane->layer, ATMEL_XLCDC_LAYER_DMA_CFG, + ATMEL_HLCDC_LAYER_DMA_BLEN_INCR16 | state->ahb_id); + + cfg = ATMEL_XLCDC_LAYER_DMA | ATMEL_XLCDC_LAYER_REP; + + if (plane->base.type != DRM_PLANE_TYPE_PRIMARY) { + /* + * Alpha Blending bits specific to SAM9X7 SoC + */ + cfg |= ATMEL_XLCDC_LAYER_SFACTC_A0_MULT_AS | + ATMEL_XLCDC_LAYER_SFACTA_ONE | + ATMEL_XLCDC_LAYER_DFACTC_M_A0_MULT_AS | + ATMEL_XLCDC_LAYER_DFACTA_ONE; + if (format->has_alpha) + cfg |= ATMEL_XLCDC_LAYER_A0(0xff); + else + cfg |= ATMEL_XLCDC_LAYER_A0(state->base.alpha); + } + + if (state->disc_h && state->disc_w) + cfg |= ATMEL_XLCDC_LAYER_DISCEN; + + atmel_hlcdc_layer_write_cfg(&plane->layer, desc->layout.general_config, + cfg); +} + static void atmel_hlcdc_plane_update_format(struct atmel_hlcdc_plane *plane, struct atmel_hlcdc_plane_state *state) { @@ -437,36 +522,55 @@ static void atmel_hlcdc_plane_update_clut(struct atmel_hlcdc_plane *plane, } } +static void atmel_hlcdc_update_buffers(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state, + u32 sr, int i) +{ + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_HLCDC_LAYER_PLANE_HEAD(i), + state->dscrs[i]->self); + + if (sr & ATMEL_HLCDC_LAYER_EN) + return; + + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_HLCDC_LAYER_PLANE_ADDR(i), + state->dscrs[i]->addr); + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_HLCDC_LAYER_PLANE_CTRL(i), + state->dscrs[i]->ctrl); + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_HLCDC_LAYER_PLANE_NEXT(i), + state->dscrs[i]->self); +} + +static void atmel_xlcdc_update_buffers(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_plane_state *state, + u32 sr, int i) +{ + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_XLCDC_LAYER_PLANE_ADDR(i), + state->dscrs[i]->addr); +} + static void atmel_hlcdc_plane_update_buffers(struct atmel_hlcdc_plane *plane, - struct atmel_hlcdc_plane_state *state) + struct atmel_hlcdc_plane_state *state) { const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private; struct drm_framebuffer *fb = state->base.fb; u32 sr; int i; - sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR); + if (!dc->desc->is_xlcdc) + sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR); for (i = 0; i < state->nplanes; i++) { struct drm_gem_dma_object *gem = drm_fb_dma_get_gem_obj(fb, i); state->dscrs[i]->addr = gem->dma_addr + state->offsets[i]; - atmel_hlcdc_layer_write_reg(&plane->layer, - ATMEL_HLCDC_LAYER_PLANE_HEAD(i), - state->dscrs[i]->self); - - if (!(sr & ATMEL_HLCDC_LAYER_EN)) { - atmel_hlcdc_layer_write_reg(&plane->layer, - ATMEL_HLCDC_LAYER_PLANE_ADDR(i), - state->dscrs[i]->addr); - atmel_hlcdc_layer_write_reg(&plane->layer, - ATMEL_HLCDC_LAYER_PLANE_CTRL(i), - state->dscrs[i]->ctrl); - atmel_hlcdc_layer_write_reg(&plane->layer, - ATMEL_HLCDC_LAYER_PLANE_NEXT(i), - state->dscrs[i]->self); - } + dc->desc->ops->lcdc_update_buffers(plane, state, sr, i); if (desc->layout.xstride[i]) atmel_hlcdc_layer_write_cfg(&plane->layer, @@ -712,11 +816,8 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, return 0; } -static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p, - struct drm_atomic_state *state) +static void atmel_hlcdc_atomic_disable(struct atmel_hlcdc_plane *plane) { - struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); - /* Disable interrupts */ atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IDR, 0xffffffff); @@ -731,6 +832,70 @@ static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p, atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR); } +static void atmel_xlcdc_atomic_disable(struct atmel_hlcdc_plane *plane) +{ + /* Disable interrupts */ + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IDR, + 0xffffffff); + + /* Disable the layer */ + atmel_hlcdc_layer_write_reg(&plane->layer, + ATMEL_XLCDC_LAYER_ENR, 0); + + /* Clear all pending interrupts */ + atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR); +} + +static void atmel_hlcdc_plane_atomic_disable(struct drm_plane *p, + struct drm_atomic_state *state) +{ + struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private; + + dc->desc->ops->lcdc_atomic_disable(plane); +} + +static void atmel_hlcdc_atomic_update(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_dc *dc) +{ + u32 sr; + + /* Enable the overrun interrupts. */ + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER, + ATMEL_HLCDC_LAYER_OVR_IRQ(0) | + ATMEL_HLCDC_LAYER_OVR_IRQ(1) | + ATMEL_HLCDC_LAYER_OVR_IRQ(2)); + + /* Apply the new config at the next SOF event. */ + sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR); + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER, + ATMEL_HLCDC_LAYER_UPDATE | + (sr & ATMEL_HLCDC_LAYER_EN ? + ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN)); +} + +static void atmel_xlcdc_atomic_update(struct atmel_hlcdc_plane *plane, + struct atmel_hlcdc_dc *dc) +{ + /* Enable the overrun interrupts. */ + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_IER, + ATMEL_XLCDC_LAYER_OVR_IRQ(0) | + ATMEL_XLCDC_LAYER_OVR_IRQ(1) | + ATMEL_XLCDC_LAYER_OVR_IRQ(2)); + + atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_XLCDC_LAYER_ENR, + ATMEL_XLCDC_LAYER_EN); + + /* + * Updating XLCDC_xxxCFGx, XLCDC_xxxFBA and XLCDC_xxxEN, + * (where xxx indicates each layer) requires writing one to the + * Update Attribute field for each layer in LCDC_ATTRE register for SAM9X7. + */ + regmap_write(dc->hlcdc->regmap, ATMEL_XLCDC_ATTRE, ATMEL_XLCDC_BASE_UPDATE | + ATMEL_XLCDC_OVR1_UPDATE | ATMEL_XLCDC_OVR3_UPDATE | + ATMEL_XLCDC_HEO_UPDATE); +} + static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p, struct drm_atomic_state *state) { @@ -739,7 +904,7 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p, struct atmel_hlcdc_plane *plane = drm_plane_to_atmel_hlcdc_plane(p); struct atmel_hlcdc_plane_state *hstate = drm_plane_state_to_atmel_hlcdc_plane_state(new_s); - u32 sr; + struct atmel_hlcdc_dc *dc = p->dev->dev_private; if (!new_s->crtc || !new_s->fb) return; @@ -750,29 +915,83 @@ static void atmel_hlcdc_plane_atomic_update(struct drm_plane *p, } atmel_hlcdc_plane_update_pos_and_size(plane, hstate); - atmel_hlcdc_plane_update_general_settings(plane, hstate); + dc->desc->ops->lcdc_update_general_settings(plane, hstate); atmel_hlcdc_plane_update_format(plane, hstate); atmel_hlcdc_plane_update_clut(plane, hstate); atmel_hlcdc_plane_update_buffers(plane, hstate); atmel_hlcdc_plane_update_disc_area(plane, hstate); - /* Enable the overrun interrupts. */ - atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_IER, - ATMEL_HLCDC_LAYER_OVR_IRQ(0) | - ATMEL_HLCDC_LAYER_OVR_IRQ(1) | - ATMEL_HLCDC_LAYER_OVR_IRQ(2)); + dc->desc->ops->lcdc_atomic_update(plane, dc); +} - /* Apply the new config at the next SOF event. */ - sr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHSR); - atmel_hlcdc_layer_write_reg(&plane->layer, ATMEL_HLCDC_LAYER_CHER, - ATMEL_HLCDC_LAYER_UPDATE | - (sr & ATMEL_HLCDC_LAYER_EN ? - ATMEL_HLCDC_LAYER_A2Q : ATMEL_HLCDC_LAYER_EN)); +static void atmel_hlcdc_csc_init(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc) +{ + /* + * TODO: declare a "yuv-to-rgb-conv-factors" property to let + * userspace modify these factors (using a BLOB property ?). + */ + static const u32 hlcdc_csc_coeffs[] = { + 0x4c900091, + 0x7a5f5090, + 0x40040890 + }; + + for (int i = 0; i < ARRAY_SIZE(hlcdc_csc_coeffs); i++) { + atmel_hlcdc_layer_write_cfg(&plane->layer, + desc->layout.csc + i, + hlcdc_csc_coeffs[i]); + } +} + +static void atmel_xlcdc_csc_init(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc) +{ + /* + * yuv-to-rgb-conv-factors are now defined from LCDC_HEOCFG16 to + * LCDC_HEOCFG21 registers in SAM9X7. + */ + static const u32 xlcdc_csc_coeffs[] = { + 0x00000488, + 0x00000648, + 0x1EA00480, + 0x00001D28, + 0x08100480, + 0x00000000, + 0x00000007 + }; + + for (int i = 0; i < ARRAY_SIZE(xlcdc_csc_coeffs); i++) { + atmel_hlcdc_layer_write_cfg(&plane->layer, + desc->layout.csc + i, + xlcdc_csc_coeffs[i]); + } + + if (desc->layout.vxs_config && desc->layout.hxs_config) { + /* + * Updating vxs.config and hxs.config fixes the + * Green Color Issue in SAM9X7 EGT Video Player App + */ + atmel_hlcdc_layer_write_cfg(&plane->layer, + desc->layout.vxs_config, + ATMEL_XLCDC_LAYER_VXSYCFG_ONE | + ATMEL_XLCDC_LAYER_VXSYTAP2_ENABLE | + ATMEL_XLCDC_LAYER_VXSCCFG_ONE | + ATMEL_XLCDC_LAYER_VXSCTAP2_ENABLE); + + atmel_hlcdc_layer_write_cfg(&plane->layer, + desc->layout.hxs_config, + ATMEL_XLCDC_LAYER_HXSYCFG_ONE | + ATMEL_XLCDC_LAYER_HXSYTAP2_ENABLE | + ATMEL_XLCDC_LAYER_HXSCCFG_ONE | + ATMEL_XLCDC_LAYER_HXSCTAP2_ENABLE); + } } static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane) { const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private; if (desc->type == ATMEL_HLCDC_OVERLAY_LAYER || desc->type == ATMEL_HLCDC_CURSOR_LAYER) { @@ -796,31 +1015,16 @@ static int atmel_hlcdc_plane_init_properties(struct atmel_hlcdc_plane *plane) return ret; } - if (desc->layout.csc) { - /* - * TODO: decare a "yuv-to-rgb-conv-factors" property to let - * userspace modify these factors (using a BLOB property ?). - */ - atmel_hlcdc_layer_write_cfg(&plane->layer, - desc->layout.csc, - 0x4c900091); - atmel_hlcdc_layer_write_cfg(&plane->layer, - desc->layout.csc + 1, - 0x7a5f5090); - atmel_hlcdc_layer_write_cfg(&plane->layer, - desc->layout.csc + 2, - 0x40040890); - } + if (desc->layout.csc) + dc->desc->ops->lcdc_csc_init(plane, desc); return 0; } -void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane) +static void atmel_hlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc) { - const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; - u32 isr; - - isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR); + u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_HLCDC_LAYER_ISR); /* * There's not much we can do in case of overrun except informing @@ -834,6 +1038,51 @@ void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane) desc->name); } +static void atmel_xlcdc_irq_dbg(struct atmel_hlcdc_plane *plane, + const struct atmel_hlcdc_layer_desc *desc) +{ + u32 isr = atmel_hlcdc_layer_read_reg(&plane->layer, ATMEL_XLCDC_LAYER_ISR); + + /* + * There's not much we can do in case of overrun except informing + * the user. However, we are in interrupt context here, hence the + * use of dev_dbg(). + */ + if (isr & + (ATMEL_XLCDC_LAYER_OVR_IRQ(0) | ATMEL_XLCDC_LAYER_OVR_IRQ(1) | + ATMEL_XLCDC_LAYER_OVR_IRQ(2))) + dev_dbg(plane->base.dev->dev, "overrun on plane %s\n", + desc->name); +} + +void atmel_hlcdc_plane_irq(struct atmel_hlcdc_plane *plane) +{ + const struct atmel_hlcdc_layer_desc *desc = plane->layer.desc; + struct atmel_hlcdc_dc *dc = plane->base.dev->dev_private; + + dc->desc->ops->lcdc_irq_dbg(plane, desc); +} + +const struct atmel_lcdc_dc_ops atmel_hlcdc_ops = { + .plane_setup_scaler = atmel_hlcdc_plane_setup_scaler, + .lcdc_update_buffers = atmel_hlcdc_update_buffers, + .lcdc_atomic_disable = atmel_hlcdc_atomic_disable, + .lcdc_update_general_settings = atmel_hlcdc_plane_update_general_settings, + .lcdc_atomic_update = atmel_hlcdc_atomic_update, + .lcdc_csc_init = atmel_hlcdc_csc_init, + .lcdc_irq_dbg = atmel_hlcdc_irq_dbg, +}; + +const struct atmel_lcdc_dc_ops atmel_xlcdc_ops = { + .plane_setup_scaler = atmel_xlcdc_plane_setup_scaler, + .lcdc_update_buffers = atmel_xlcdc_update_buffers, + .lcdc_atomic_disable = atmel_xlcdc_atomic_disable, + .lcdc_update_general_settings = atmel_xlcdc_plane_update_general_settings, + .lcdc_atomic_update = atmel_xlcdc_atomic_update, + .lcdc_csc_init = atmel_xlcdc_csc_init, + .lcdc_irq_dbg = atmel_xlcdc_irq_dbg, +}; + static const struct drm_plane_helper_funcs atmel_hlcdc_layer_plane_helper_funcs = { .atomic_check = atmel_hlcdc_plane_atomic_check, .atomic_update = atmel_hlcdc_plane_atomic_update, diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 9360b63ad37c..b5dbff21c187 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -234,28 +234,6 @@ static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) return ret < 0 ? ret : 0; } -static void -analogix_dp_set_lane_lane_pre_emphasis(struct analogix_dp_device *dp, - int pre_emphasis, int lane) -{ - switch (lane) { - case 0: - analogix_dp_set_lane0_pre_emphasis(dp, pre_emphasis); - break; - case 1: - analogix_dp_set_lane1_pre_emphasis(dp, pre_emphasis); - break; - - case 2: - analogix_dp_set_lane2_pre_emphasis(dp, pre_emphasis); - break; - - case 3: - analogix_dp_set_lane3_pre_emphasis(dp, pre_emphasis); - break; - } -} - static int analogix_dp_link_start(struct analogix_dp_device *dp) { u8 buf[4]; @@ -286,10 +264,12 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp) return retval; } - /* Set TX pre-emphasis to minimum */ + /* Set TX voltage-swing and pre-emphasis to minimum */ for (lane = 0; lane < lane_count; lane++) - analogix_dp_set_lane_lane_pre_emphasis(dp, - PRE_EMPHASIS_LEVEL_0, lane); + dp->link_train.training_lane[lane] = + DP_TRAIN_VOLTAGE_SWING_LEVEL_0 | + DP_TRAIN_PRE_EMPH_LEVEL_0; + analogix_dp_set_lane_link_training(dp); /* Wait for PLL lock */ pll_tries = 0; @@ -384,54 +364,6 @@ static unsigned char analogix_dp_get_adjust_request_pre_emphasis( return ((link_value >> shift) & 0xc) >> 2; } -static void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp, - u8 training_lane_set, int lane) -{ - switch (lane) { - case 0: - analogix_dp_set_lane0_link_training(dp, training_lane_set); - break; - case 1: - analogix_dp_set_lane1_link_training(dp, training_lane_set); - break; - - case 2: - analogix_dp_set_lane2_link_training(dp, training_lane_set); - break; - - case 3: - analogix_dp_set_lane3_link_training(dp, training_lane_set); - break; - } -} - -static unsigned int -analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, - int lane) -{ - u32 reg; - - switch (lane) { - case 0: - reg = analogix_dp_get_lane0_link_training(dp); - break; - case 1: - reg = analogix_dp_get_lane1_link_training(dp); - break; - case 2: - reg = analogix_dp_get_lane2_link_training(dp); - break; - case 3: - reg = analogix_dp_get_lane3_link_training(dp); - break; - default: - WARN_ON(1); - return 0; - } - - return reg; -} - static void analogix_dp_reduce_link_rate(struct analogix_dp_device *dp) { analogix_dp_training_pattern_dis(dp); @@ -478,11 +410,6 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) if (retval < 0) return retval; - retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1, - adjust_request, 2); - if (retval < 0) - return retval; - if (analogix_dp_clock_recovery_ok(link_status, lane_count) == 0) { /* set training pattern 2 for EQ */ analogix_dp_set_training_pattern(dp, TRAINING_PTN2); @@ -495,38 +422,37 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) dev_dbg(dp->dev, "Link Training Clock Recovery success\n"); dp->link_train.lt_state = EQUALIZER_TRAINING; - } else { - for (lane = 0; lane < lane_count; lane++) { - training_lane = analogix_dp_get_lane_link_training( - dp, lane); - voltage_swing = analogix_dp_get_adjust_request_voltage( - adjust_request, lane); - pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis( - adjust_request, lane); - - if (DPCD_VOLTAGE_SWING_GET(training_lane) == - voltage_swing && - DPCD_PRE_EMPHASIS_GET(training_lane) == - pre_emphasis) - dp->link_train.cr_loop[lane]++; - - if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || - voltage_swing == VOLTAGE_LEVEL_3 || - pre_emphasis == PRE_EMPHASIS_LEVEL_3) { - dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", - dp->link_train.cr_loop[lane], - voltage_swing, pre_emphasis); - analogix_dp_reduce_link_rate(dp); - return -EIO; - } + + return 0; + } + + retval = drm_dp_dpcd_read(&dp->aux, DP_ADJUST_REQUEST_LANE0_1, + adjust_request, 2); + if (retval < 0) + return retval; + + for (lane = 0; lane < lane_count; lane++) { + training_lane = analogix_dp_get_lane_link_training(dp, lane); + voltage_swing = analogix_dp_get_adjust_request_voltage(adjust_request, lane); + pre_emphasis = analogix_dp_get_adjust_request_pre_emphasis(adjust_request, lane); + + if (DPCD_VOLTAGE_SWING_GET(training_lane) == voltage_swing && + DPCD_PRE_EMPHASIS_GET(training_lane) == pre_emphasis) + dp->link_train.cr_loop[lane]++; + + if (dp->link_train.cr_loop[lane] == MAX_CR_LOOP || + voltage_swing == VOLTAGE_LEVEL_3 || + pre_emphasis == PRE_EMPHASIS_LEVEL_3) { + dev_err(dp->dev, "CR Max reached (%d,%d,%d)\n", + dp->link_train.cr_loop[lane], + voltage_swing, pre_emphasis); + analogix_dp_reduce_link_rate(dp); + return -EIO; } } analogix_dp_get_adjust_training_lane(dp, adjust_request); - - for (lane = 0; lane < lane_count; lane++) - analogix_dp_set_lane_link_training(dp, - dp->link_train.training_lane[lane], lane); + analogix_dp_set_lane_link_training(dp); retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->link_train.training_lane, lane_count); @@ -538,7 +464,7 @@ static int analogix_dp_process_clock_recovery(struct analogix_dp_device *dp) static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) { - int lane, lane_count, retval; + int lane_count, retval; u32 reg; u8 link_align, link_status[2], adjust_request[2]; @@ -598,9 +524,7 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) return -EIO; } - for (lane = 0; lane < lane_count; lane++) - analogix_dp_set_lane_link_training(dp, - dp->link_train.training_lane[lane], lane); + analogix_dp_set_lane_link_training(dp); retval = drm_dp_dpcd_write(&dp->aux, DP_TRAINING_LANE0_SET, dp->link_train.training_lane, lane_count); @@ -712,7 +636,7 @@ static int analogix_dp_full_link_train(struct analogix_dp_device *dp, static int analogix_dp_fast_link_train(struct analogix_dp_device *dp) { - int i, ret; + int ret; u8 link_align, link_status[2]; enum pll_status status; @@ -720,11 +644,7 @@ static int analogix_dp_fast_link_train(struct analogix_dp_device *dp) analogix_dp_set_link_bandwidth(dp, dp->link_train.link_rate); analogix_dp_set_lane_count(dp, dp->link_train.lane_count); - - for (i = 0; i < dp->link_train.lane_count; i++) { - analogix_dp_set_lane_link_training(dp, - dp->link_train.training_lane[i], i); - } + analogix_dp_set_lane_link_training(dp); ret = readx_poll_timeout(analogix_dp_get_pll_lock_status, dp, status, status != PLL_UNLOCKED, 120, diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 433f2d7efa0c..382b2f068ab9 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -213,26 +213,8 @@ void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, bool enable); void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, enum pattern_set pattern); -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, - u32 level); -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, - u32 level); -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, - u32 level); -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, - u32 level); -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, - u32 training_lane); -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, - u32 training_lane); -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, - u32 training_lane); -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, - u32 training_lane); -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp); -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp); -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp); -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp); +void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp); +u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane); void analogix_dp_reset_macro(struct analogix_dp_device *dp); void analogix_dp_init_video(struct analogix_dp_device *dp); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index 6a4f20fccf84..d267cf05cbca 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -557,6 +557,20 @@ void analogix_dp_get_lane_count(struct analogix_dp_device *dp, u32 *count) *count = reg; } +void analogix_dp_set_lane_link_training(struct analogix_dp_device *dp) +{ + u8 lane; + + for (lane = 0; lane < dp->link_train.lane_count; lane++) + writel(dp->link_train.training_lane[lane], + dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane); +} + +u32 analogix_dp_get_lane_link_training(struct analogix_dp_device *dp, u8 lane) +{ + return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL + 4 * lane); +} + void analogix_dp_enable_enhanced_mode(struct analogix_dp_device *dp, bool enable) { @@ -606,106 +620,6 @@ void analogix_dp_set_training_pattern(struct analogix_dp_device *dp, } } -void analogix_dp_set_lane0_pre_emphasis(struct analogix_dp_device *dp, - u32 level) -{ - u32 reg; - - reg = readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); - reg &= ~PRE_EMPHASIS_SET_MASK; - reg |= level << PRE_EMPHASIS_SET_SHIFT; - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane1_pre_emphasis(struct analogix_dp_device *dp, - u32 level) -{ - u32 reg; - - reg = readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); - reg &= ~PRE_EMPHASIS_SET_MASK; - reg |= level << PRE_EMPHASIS_SET_SHIFT; - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane2_pre_emphasis(struct analogix_dp_device *dp, - u32 level) -{ - u32 reg; - - reg = readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); - reg &= ~PRE_EMPHASIS_SET_MASK; - reg |= level << PRE_EMPHASIS_SET_SHIFT; - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane3_pre_emphasis(struct analogix_dp_device *dp, - u32 level) -{ - u32 reg; - - reg = readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); - reg &= ~PRE_EMPHASIS_SET_MASK; - reg |= level << PRE_EMPHASIS_SET_SHIFT; - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane0_link_training(struct analogix_dp_device *dp, - u32 training_lane) -{ - u32 reg; - - reg = training_lane; - writel(reg, dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane1_link_training(struct analogix_dp_device *dp, - u32 training_lane) -{ - u32 reg; - - reg = training_lane; - writel(reg, dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane2_link_training(struct analogix_dp_device *dp, - u32 training_lane) -{ - u32 reg; - - reg = training_lane; - writel(reg, dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); -} - -void analogix_dp_set_lane3_link_training(struct analogix_dp_device *dp, - u32 training_lane) -{ - u32 reg; - - reg = training_lane; - writel(reg, dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); -} - -u32 analogix_dp_get_lane0_link_training(struct analogix_dp_device *dp) -{ - return readl(dp->reg_base + ANALOGIX_DP_LN0_LINK_TRAINING_CTL); -} - -u32 analogix_dp_get_lane1_link_training(struct analogix_dp_device *dp) -{ - return readl(dp->reg_base + ANALOGIX_DP_LN1_LINK_TRAINING_CTL); -} - -u32 analogix_dp_get_lane2_link_training(struct analogix_dp_device *dp) -{ - return readl(dp->reg_base + ANALOGIX_DP_LN2_LINK_TRAINING_CTL); -} - -u32 analogix_dp_get_lane3_link_training(struct analogix_dp_device *dp) -{ - return readl(dp->reg_base + ANALOGIX_DP_LN3_LINK_TRAINING_CTL); -} - void analogix_dp_reset_macro(struct analogix_dp_device *dp) { u32 reg; @@ -1027,7 +941,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, u32 status_reg; u8 *buffer = msg->buffer; unsigned int i; - int num_transferred = 0; int ret; /* Buffer size of AUX CH is 16 bytes */ @@ -1079,7 +992,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, reg = buffer[i]; writel(reg, dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 4 * i); - num_transferred++; } } @@ -1127,7 +1039,6 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, reg = readl(dp->reg_base + ANALOGIX_DP_BUF_DATA_0 + 4 * i); buffer[i] = (unsigned char)reg; - num_transferred++; } } @@ -1144,7 +1055,7 @@ ssize_t analogix_dp_transfer(struct analogix_dp_device *dp, (msg->request & ~DP_AUX_I2C_MOT) == DP_AUX_NATIVE_READ) msg->reply = DP_AUX_NATIVE_REPLY_ACK; - return num_transferred > 0 ? num_transferred : -EBUSY; + return msg->size; aux_error: /* if aux err happen, reset aux */ diff --git a/drivers/gpu/drm/ci/build.sh b/drivers/gpu/drm/ci/build.sh index 106f2d40d222..28a495c0c39c 100644 --- a/drivers/gpu/drm/ci/build.sh +++ b/drivers/gpu/drm/ci/build.sh @@ -12,6 +12,9 @@ rm -rf .git/rebase-apply apt-get update apt-get install -y libssl-dev +# for msm header validation +apt-get install -y python3-lxml + if [[ "$KERNEL_ARCH" = "arm64" ]]; then GCC_ARCH="aarch64-linux-gnu" DEBIAN_ARCH="arm64" diff --git a/drivers/gpu/drm/ci/build.yml b/drivers/gpu/drm/ci/build.yml index 17ab38304885..9c198239033d 100644 --- a/drivers/gpu/drm/ci/build.yml +++ b/drivers/gpu/drm/ci/build.yml @@ -106,6 +106,7 @@ build-nodebugfs:arm64: extends: .build:arm64 variables: DISABLE_KCONFIGS: "DEBUG_FS" + ENABLE_KCONFIGS: "EXPERT DRM_MSM_VALIDATE_XML" build:x86_64: extends: .build:x86_64 diff --git a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c index 1aab0c9ae52f..e986d9823528 100644 --- a/drivers/gpu/drm/panel/panel-newvision-nv3052c.c +++ b/drivers/gpu/drm/panel/panel-newvision-nv3052c.c @@ -433,6 +433,202 @@ static const struct nv3052c_reg fs035vg158_panel_regs[] = { { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 }; + +static const struct nv3052c_reg wl_355608_a8_panel_regs[] = { + // EXTC Command set enable, select page 1 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x01 }, + // Mostly unknown registers + { 0xe3, 0x00 }, + { 0x40, 0x00 }, + { 0x03, 0x40 }, + { 0x04, 0x00 }, + { 0x05, 0x03 }, + { 0x08, 0x00 }, + { 0x09, 0x07 }, + { 0x0a, 0x01 }, + { 0x0b, 0x32 }, + { 0x0c, 0x32 }, + { 0x0d, 0x0b }, + { 0x0e, 0x00 }, + { 0x23, 0xa0 }, + { 0x24, 0x0c }, + { 0x25, 0x06 }, + { 0x26, 0x14 }, + { 0x27, 0x14 }, + { 0x38, 0xcc }, // VCOM_ADJ1 + { 0x39, 0xd7 }, // VCOM_ADJ2 + { 0x3a, 0x44 }, // VCOM_ADJ3 + { 0x28, 0x40 }, + { 0x29, 0x01 }, + { 0x2a, 0xdf }, + { 0x49, 0x3c }, + { 0x91, 0x77 }, // EXTPW_CTRL2 + { 0x92, 0x77 }, // EXTPW_CTRL3 + { 0xa0, 0x55 }, + { 0xa1, 0x50 }, + { 0xa4, 0x9c }, + { 0xa7, 0x02 }, + { 0xa8, 0x01 }, + { 0xa9, 0x01 }, + { 0xaa, 0xfc }, + { 0xab, 0x28 }, + { 0xac, 0x06 }, + { 0xad, 0x06 }, + { 0xae, 0x06 }, + { 0xaf, 0x03 }, + { 0xb0, 0x08 }, + { 0xb1, 0x26 }, + { 0xb2, 0x28 }, + { 0xb3, 0x28 }, + { 0xb4, 0x33 }, + { 0xb5, 0x08 }, + { 0xb6, 0x26 }, + { 0xb7, 0x08 }, + { 0xb8, 0x26 }, + { 0xf0, 0x00 }, + { 0xf6, 0xc0 }, + // EXTC Command set enable, select page 2 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, + // Set gray scale voltage to adjust gamma + { 0xb0, 0x0b }, // PGAMVR0 + { 0xb1, 0x16 }, // PGAMVR1 + { 0xb2, 0x17 }, // PGAMVR2 + { 0xb3, 0x2c }, // PGAMVR3 + { 0xb4, 0x32 }, // PGAMVR4 + { 0xb5, 0x3b }, // PGAMVR5 + { 0xb6, 0x29 }, // PGAMPR0 + { 0xb7, 0x40 }, // PGAMPR1 + { 0xb8, 0x0d }, // PGAMPK0 + { 0xb9, 0x05 }, // PGAMPK1 + { 0xba, 0x12 }, // PGAMPK2 + { 0xbb, 0x10 }, // PGAMPK3 + { 0xbc, 0x12 }, // PGAMPK4 + { 0xbd, 0x15 }, // PGAMPK5 + { 0xbe, 0x19 }, // PGAMPK6 + { 0xbf, 0x0e }, // PGAMPK7 + { 0xc0, 0x16 }, // PGAMPK8 + { 0xc1, 0x0a }, // PGAMPK9 + // Set gray scale voltage to adjust gamma + { 0xd0, 0x0c }, // NGAMVR0 + { 0xd1, 0x17 }, // NGAMVR0 + { 0xd2, 0x14 }, // NGAMVR1 + { 0xd3, 0x2e }, // NGAMVR2 + { 0xd4, 0x32 }, // NGAMVR3 + { 0xd5, 0x3c }, // NGAMVR4 + { 0xd6, 0x22 }, // NGAMPR0 + { 0xd7, 0x3d }, // NGAMPR1 + { 0xd8, 0x0d }, // NGAMPK0 + { 0xd9, 0x07 }, // NGAMPK1 + { 0xda, 0x13 }, // NGAMPK2 + { 0xdb, 0x13 }, // NGAMPK3 + { 0xdc, 0x11 }, // NGAMPK4 + { 0xdd, 0x15 }, // NGAMPK5 + { 0xde, 0x19 }, // NGAMPK6 + { 0xdf, 0x10 }, // NGAMPK7 + { 0xe0, 0x17 }, // NGAMPK8 + { 0xe1, 0x0a }, // NGAMPK9 + // EXTC Command set enable, select page 3 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x03 }, + // Set various timing settings + { 0x00, 0x2a }, // GIP_VST_1 + { 0x01, 0x2a }, // GIP_VST_2 + { 0x02, 0x2a }, // GIP_VST_3 + { 0x03, 0x2a }, // GIP_VST_4 + { 0x04, 0x61 }, // GIP_VST_5 + { 0x05, 0x80 }, // GIP_VST_6 + { 0x06, 0xc7 }, // GIP_VST_7 + { 0x07, 0x01 }, // GIP_VST_8 + { 0x08, 0x03 }, // GIP_VST_9 + { 0x09, 0x04 }, // GIP_VST_10 + { 0x70, 0x22 }, // GIP_ECLK1 + { 0x71, 0x80 }, // GIP_ECLK2 + { 0x30, 0x2a }, // GIP_CLK_1 + { 0x31, 0x2a }, // GIP_CLK_2 + { 0x32, 0x2a }, // GIP_CLK_3 + { 0x33, 0x2a }, // GIP_CLK_4 + { 0x34, 0x61 }, // GIP_CLK_5 + { 0x35, 0xc5 }, // GIP_CLK_6 + { 0x36, 0x80 }, // GIP_CLK_7 + { 0x37, 0x23 }, // GIP_CLK_8 + { 0x40, 0x03 }, // GIP_CLKA_1 + { 0x41, 0x04 }, // GIP_CLKA_2 + { 0x42, 0x05 }, // GIP_CLKA_3 + { 0x43, 0x06 }, // GIP_CLKA_4 + { 0x44, 0x11 }, // GIP_CLKA_5 + { 0x45, 0xe8 }, // GIP_CLKA_6 + { 0x46, 0xe9 }, // GIP_CLKA_7 + { 0x47, 0x11 }, // GIP_CLKA_8 + { 0x48, 0xea }, // GIP_CLKA_9 + { 0x49, 0xeb }, // GIP_CLKA_10 + { 0x50, 0x07 }, // GIP_CLKB_1 + { 0x51, 0x08 }, // GIP_CLKB_2 + { 0x52, 0x09 }, // GIP_CLKB_3 + { 0x53, 0x0a }, // GIP_CLKB_4 + { 0x54, 0x11 }, // GIP_CLKB_5 + { 0x55, 0xec }, // GIP_CLKB_6 + { 0x56, 0xed }, // GIP_CLKB_7 + { 0x57, 0x11 }, // GIP_CLKB_8 + { 0x58, 0xef }, // GIP_CLKB_9 + { 0x59, 0xf0 }, // GIP_CLKB_10 + // Map internal GOA signals to GOA output pad + { 0xb1, 0x01 }, // PANELD2U2 + { 0xb4, 0x15 }, // PANELD2U5 + { 0xb5, 0x16 }, // PANELD2U6 + { 0xb6, 0x09 }, // PANELD2U7 + { 0xb7, 0x0f }, // PANELD2U8 + { 0xb8, 0x0d }, // PANELD2U9 + { 0xb9, 0x0b }, // PANELD2U10 + { 0xba, 0x00 }, // PANELD2U11 + { 0xc7, 0x02 }, // PANELD2U24 + { 0xca, 0x17 }, // PANELD2U27 + { 0xcb, 0x18 }, // PANELD2U28 + { 0xcc, 0x0a }, // PANELD2U29 + { 0xcd, 0x10 }, // PANELD2U30 + { 0xce, 0x0e }, // PANELD2U31 + { 0xcf, 0x0c }, // PANELD2U32 + { 0xd0, 0x00 }, // PANELD2U33 + // Map internal GOA signals to GOA output pad + { 0x81, 0x00 }, // PANELU2D2 + { 0x84, 0x15 }, // PANELU2D5 + { 0x85, 0x16 }, // PANELU2D6 + { 0x86, 0x10 }, // PANELU2D7 + { 0x87, 0x0a }, // PANELU2D8 + { 0x88, 0x0c }, // PANELU2D9 + { 0x89, 0x0e }, // PANELU2D10 + { 0x8a, 0x02 }, // PANELU2D11 + { 0x97, 0x00 }, // PANELU2D24 + { 0x9a, 0x17 }, // PANELU2D27 + { 0x9b, 0x18 }, // PANELU2D28 + { 0x9c, 0x0f }, // PANELU2D29 + { 0x9d, 0x09 }, // PANELU2D30 + { 0x9e, 0x0b }, // PANELU2D31 + { 0x9f, 0x0d }, // PANELU2D32 + { 0xa0, 0x01 }, // PANELU2D33 + // EXTC Command set enable, select page 2 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x02 }, + // Unknown registers + { 0x01, 0x01 }, + { 0x02, 0xda }, + { 0x03, 0xba }, + { 0x04, 0xa8 }, + { 0x05, 0x9a }, + { 0x06, 0x70 }, + { 0x07, 0xff }, + { 0x08, 0x91 }, + { 0x09, 0x90 }, + { 0x0a, 0xff }, + { 0x0b, 0x8f }, + { 0x0c, 0x60 }, + { 0x0d, 0x58 }, + { 0x0e, 0x48 }, + { 0x0f, 0x38 }, + { 0x10, 0x2b }, + // EXTC Command set enable, select page 0 + { 0xff, 0x30 }, { 0xff, 0x52 }, { 0xff, 0x00 }, + // Display Access Control + { 0x36, 0x0a }, // bgr = 1, ss = 1, gs = 0 +}; + static inline struct nv3052c *to_nv3052c(struct drm_panel *panel) { return container_of(panel, struct nv3052c, panel); @@ -670,6 +866,21 @@ static const struct drm_display_mode fs035vg158_modes[] = { }, }; +static const struct drm_display_mode wl_355608_a8_mode[] = { + { + .clock = 24000, + .hdisplay = 640, + .hsync_start = 640 + 64, + .hsync_end = 640 + 64 + 20, + .htotal = 640 + 64 + 20 + 46, + .vdisplay = 480, + .vsync_start = 480 + 21, + .vsync_end = 480 + 21 + 4, + .vtotal = 480 + 21 + 4 + 15, + .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, + }, +}; + static const struct nv3052c_panel_info ltk035c5444t_panel_info = { .display_modes = ltk035c5444t_modes, .num_modes = ARRAY_SIZE(ltk035c5444t_modes), @@ -692,9 +903,21 @@ static const struct nv3052c_panel_info fs035vg158_panel_info = { .panel_regs_len = ARRAY_SIZE(fs035vg158_panel_regs), }; +static const struct nv3052c_panel_info wl_355608_a8_panel_info = { + .display_modes = wl_355608_a8_mode, + .num_modes = ARRAY_SIZE(wl_355608_a8_mode), + .width_mm = 150, + .height_mm = 94, + .bus_format = MEDIA_BUS_FMT_RGB888_1X24, + .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE, + .panel_regs = wl_355608_a8_panel_regs, + .panel_regs_len = ARRAY_SIZE(wl_355608_a8_panel_regs), +}; + static const struct spi_device_id nv3052c_ids[] = { { "ltk035c5444t", }, { "fs035vg158", }, + { "wl-355608-a8", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(spi, nv3052c_ids); @@ -702,6 +925,7 @@ MODULE_DEVICE_TABLE(spi, nv3052c_ids); static const struct of_device_id nv3052c_of_match[] = { { .compatible = "leadtek,ltk035c5444t", .data = <k035c5444t_panel_info }, { .compatible = "fascontek,fs035vg158", .data = &fs035vg158_panel_info }, + { .compatible = "wl-355608-a8", .data = &wl_355608_a8_panel_info }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, nv3052c_of_match); @@ -719,4 +943,5 @@ module_spi_driver(nv3052c_driver); MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); MODULE_AUTHOR("Christophe Branchereau <cbranchereau@gmail.com>"); +MODULE_AUTHOR("Ryan Walklin <ryan@testtoast.com"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/gpu/drm/v3d/v3d_drv.c b/drivers/gpu/drm/v3d/v3d_drv.c index f7477488b1cc..a47f00b443d3 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.c +++ b/drivers/gpu/drm/v3d/v3d_drv.c @@ -299,9 +299,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) WARN_ON(v3d->cores > 1); /* multicore not yet implemented */ if (v3d->ver >= 71) - v3d->max_counters = ARRAY_SIZE(v3d_v71_performance_counters); + v3d->max_counters = V3D_V71_NUM_PERFCOUNTERS; else if (v3d->ver >= 42) - v3d->max_counters = ARRAY_SIZE(v3d_v42_performance_counters); + v3d->max_counters = V3D_V42_NUM_PERFCOUNTERS; else v3d->max_counters = 0; diff --git a/drivers/gpu/drm/v3d/v3d_drv.h b/drivers/gpu/drm/v3d/v3d_drv.h index 556cbb400ba0..099b962bdfde 100644 --- a/drivers/gpu/drm/v3d/v3d_drv.h +++ b/drivers/gpu/drm/v3d/v3d_drv.h @@ -351,9 +351,6 @@ struct v3d_timestamp_query { struct drm_syncobj *syncobj; }; -/* Maximum number of performance counters supported by any version of V3D */ -#define V3D_MAX_COUNTERS ARRAY_SIZE(v3d_v71_performance_counters) - /* Number of perfmons required to handle all supported performance counters */ #define V3D_MAX_PERFMONS DIV_ROUND_UP(V3D_MAX_COUNTERS, \ DRM_V3D_MAX_PERF_COUNTERS) diff --git a/drivers/gpu/drm/v3d/v3d_perfmon.c b/drivers/gpu/drm/v3d/v3d_perfmon.c index 73e2bb8bdb7f..b7d0b02e1a95 100644 --- a/drivers/gpu/drm/v3d/v3d_perfmon.c +++ b/drivers/gpu/drm/v3d/v3d_perfmon.c @@ -9,6 +9,192 @@ #define V3D_PERFMONID_MIN 1 #define V3D_PERFMONID_MAX U32_MAX +static const struct v3d_perf_counter_desc v3d_v42_performance_counters[] = { + {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"}, + {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"}, + {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"}, + {"FEP", "FEP-valid-quads", "[FEP] Valid quads"}, + {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"}, + {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"}, + {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"}, + {"TLB", "TLB-quads-with-zero-coverage", "[TLB] Quads with all pixels having zero coverage"}, + {"TLB", "TLB-quads-with-non-zero-coverage", "[TLB] Quads with any pixels having non-zero coverage"}, + {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"}, + {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"}, + {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"}, + {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"}, + {"QPU", "QPU-total-idle-clk-cycles", "[QPU] Total idle clock cycles for all QPUs"}, + {"QPU", "QPU-total-active-clk-cycles-vertex-coord-shading", "[QPU] Total active clock cycles for all QPUs doing vertex/coordinate/user shading (counts only when QPU is not stalled)"}, + {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"}, + {"QPU", "QPU-total-clk-cycles-executing-valid-instr", "[QPU] Total clock cycles for all QPUs executing valid instructions"}, + {"QPU", "QPU-total-clk-cycles-waiting-TMU", "[QPU] Total clock cycles for all QPUs stalled waiting for TMUs only (counter won't increment if QPU also stalling for another reason)"}, + {"QPU", "QPU-total-clk-cycles-waiting-scoreboard", "[QPU] Total clock cycles for all QPUs stalled waiting for Scoreboard only (counter won't increment if QPU also stalling for another reason)"}, + {"QPU", "QPU-total-clk-cycles-waiting-varyings", "[QPU] Total clock cycles for all QPUs stalled waiting for Varyings only (counter won't increment if QPU also stalling for another reason)"}, + {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"}, + {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"}, + {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"}, + {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"}, + {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"}, + {"TMU", "TMU-total-text-cache-miss", "[TMU] Total texture cache misses (number of fetches from memory/L2cache)"}, + {"VPM", "VPM-total-clk-cycles-VDW-stalled", "[VPM] Total clock cycles VDW is stalled waiting for VPM access"}, + {"VPM", "VPM-total-clk-cycles-VCD-stalled", "[VPM] Total clock cycles VCD is stalled waiting for VPM access"}, + {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"}, + {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"}, + {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"}, + {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"}, + {"CORE", "cycle-count", "[CORE] Cycle counter"}, + {"QPU", "QPU-total-clk-cycles-waiting-vertex-coord-shading", "[QPU] Total stalled clock cycles for all QPUs doing vertex/coordinate/user shading"}, + {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"}, + {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"}, + {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"}, + {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"}, + {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"}, + {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"}, + {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"}, + {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"}, + {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"}, + {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"}, + {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"}, + {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"}, + {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"}, + {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"}, + {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"}, + {"TMU", "TMU-total-config-access", "[TMU] Total config accesses"}, + {"L2T", "L2T-no-id-stalled", "[L2T] No ID stall"}, + {"L2T", "L2T-command-queue-stalled", "[L2T] Command queue full stall"}, + {"L2T", "L2T-TMU-writes", "[L2T] TMU write accesses"}, + {"TMU", "TMU-active-cycles", "[TMU] Active cycles"}, + {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"}, + {"CLE", "CLE-thread-active-cycles", "[CLE] Bin or render thread active cycles"}, + {"L2T", "L2T-TMU-reads", "[L2T] TMU read accesses"}, + {"L2T", "L2T-CLE-reads", "[L2T] CLE read accesses"}, + {"L2T", "L2T-VCD-reads", "[L2T] VCD read accesses"}, + {"L2T", "L2T-TMU-config-reads", "[L2T] TMU CFG read accesses"}, + {"L2T", "L2T-SLC0-reads", "[L2T] SLC0 read accesses"}, + {"L2T", "L2T-SLC1-reads", "[L2T] SLC1 read accesses"}, + {"L2T", "L2T-SLC2-reads", "[L2T] SLC2 read accesses"}, + {"L2T", "L2T-TMU-write-miss", "[L2T] TMU write misses"}, + {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"}, + {"L2T", "L2T-CLE-read-miss", "[L2T] CLE read misses"}, + {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"}, + {"L2T", "L2T-TMU-config-read-miss", "[L2T] TMU CFG read misses"}, + {"L2T", "L2T-SLC0-read-miss", "[L2T] SLC0 read misses"}, + {"L2T", "L2T-SLC1-read-miss", "[L2T] SLC1 read misses"}, + {"L2T", "L2T-SLC2-read-miss", "[L2T] SLC2 read misses"}, + {"CORE", "core-memory-writes", "[CORE] Total memory writes"}, + {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"}, + {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"}, + {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"}, + {"CORE", "core-memory-reads", "[CORE] Total memory reads"}, + {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"}, + {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"}, + {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"}, + {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"}, + {"GMP", "GMP-memory-reads", "[GMP] Total memory reads"}, + {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"}, + {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"}, + {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"}, + {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"}, + {"TMU", "TMU-MRU-hits", "[TMU] Total MRU hits"}, + {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"}, +}; + +static const struct v3d_perf_counter_desc v3d_v71_performance_counters[] = { + {"CORE", "cycle-count", "[CORE] Cycle counter"}, + {"CORE", "core-active", "[CORE] Bin/Render/Compute active cycles"}, + {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"}, + {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"}, + {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"}, + {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"}, + {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"}, + {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"}, + {"FEP", "FEP-valid-quads", "[FEP] Valid quads"}, + {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"}, + {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"}, + {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"}, + {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"}, + {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"}, + {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"}, + {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"}, + {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"}, + {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"}, + {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"}, + {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"}, + {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"}, + {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"}, + {"TMU", "TMU-active-cycles", "[TMU] Active cycles"}, + {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"}, + {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"}, + {"TMU", "TMU-cache-x4-active-cycles", "[TMU] Cache active cycles for x4 access"}, + {"TMU", "TMU-cache-x4-stalled-cycles", "[TMU] Cache stalled cycles for x4 access"}, + {"TMU", "TMU-total-text-quads-x4-access", "[TMU] Total texture cache x4 access"}, + {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"}, + {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"}, + {"L2T", "L2T-local", "[L2T] Local mode access"}, + {"L2T", "L2T-writeback", "[L2T] Writeback"}, + {"L2T", "L2T-zero", "[L2T] Zero"}, + {"L2T", "L2T-merge", "[L2T] Merge"}, + {"L2T", "L2T-fill", "[L2T] Fill"}, + {"L2T", "L2T-stalls-no-wid", "[L2T] Stalls because no WID available"}, + {"L2T", "L2T-stalls-no-rid", "[L2T] Stalls because no RID available"}, + {"L2T", "L2T-stalls-queue-full", "[L2T] Stalls because internal queue full"}, + {"L2T", "L2T-stalls-wrightback", "[L2T] Stalls because writeback in flight"}, + {"L2T", "L2T-stalls-mem", "[L2T] Stalls because AXI blocks read"}, + {"L2T", "L2T-stalls-fill", "[L2T] Stalls because fill pending for victim cache-line"}, + {"L2T", "L2T-hitq", "[L2T] Sent request via hit queue"}, + {"L2T", "L2T-hitq-full", "[L2T] Sent request via main queue because hit queue is full"}, + {"L2T", "L2T-stalls-read-data", "[L2T] Stalls because waiting for data from SDRAM"}, + {"L2T", "L2T-TMU-read-hits", "[L2T] TMU read hits"}, + {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"}, + {"L2T", "L2T-VCD-read-hits", "[L2T] VCD read hits"}, + {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"}, + {"L2T", "L2T-SLC-read-hits", "[L2T] SLC read hits (all slices)"}, + {"L2T", "L2T-SLC-read-miss", "[L2T] SLC read misses (all slices)"}, + {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"}, + {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"}, + {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"}, + {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"}, + {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"}, + {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"}, + {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"}, + {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"}, + {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"}, + {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"}, + {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"}, + {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"}, + {"CORE", "core-memory-writes", "[CORE] Total memory writes"}, + {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"}, + {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"}, + {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"}, + {"CORE", "core-memory-reads", "[CORE] Total memory reads"}, + {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"}, + {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"}, + {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"}, + {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"}, + {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"}, + {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"}, + {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"}, + {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"}, + {"AXI", "AXI-read-trans", "[AXI] Read transaction count"}, + {"AXI", "AXI-write-trans", "[AXI] Write transaction count"}, + {"AXI", "AXI-read-wait-cycles", "[AXI] Read total wait cycles"}, + {"AXI", "AXI-write-wait-cycles", "[AXI] Write total wait cycles"}, + {"AXI", "AXI-max-outstanding-reads", "[AXI] Maximum outstanding read transactions"}, + {"AXI", "AXI-max-outstanding-writes", "[AXI] Maximum outstanding write transactions"}, + {"QPU", "QPU-wait-bubble", "[QPU] Pipeline bubble in qcycles due all threads waiting"}, + {"QPU", "QPU-ic-miss-bubble", "[QPU] Pipeline bubble in qcycles due instruction-cache miss"}, + {"QPU", "QPU-active", "[QPU] Executed shader instruction"}, + {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"}, + {"QPU", "QPU-stalls", "[QPU] Stalled qcycles executing shader instruction"}, + {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"}, + {"QPU", "QPU-stalls-TMU", "[QPU] Stalled qcycles waiting for TMU"}, + {"QPU", "QPU-stalls-TLB", "[QPU] Stalled qcycles waiting for TLB"}, + {"QPU", "QPU-stalls-VPM", "[QPU] Stalled qcycles waiting for VPM"}, + {"QPU", "QPU-stalls-uniforms", "[QPU] Stalled qcycles waiting for uniforms"}, + {"QPU", "QPU-stalls-SFU", "[QPU] Stalled qcycles waiting for SFU"}, + {"QPU", "QPU-stalls-other", "[QPU] Stalled qcycles waiting for any other reason (vary/W/Z)"}, +}; + void v3d_perfmon_get(struct v3d_perfmon *perfmon) { if (perfmon) @@ -234,15 +420,21 @@ int v3d_perfmon_get_counter_ioctl(struct drm_device *dev, void *data, if (req->counter >= v3d->max_counters) return -EINVAL; - if (v3d->ver >= 71) { - WARN_ON(v3d->max_counters != ARRAY_SIZE(v3d_v71_performance_counters)); + BUILD_BUG_ON(ARRAY_SIZE(v3d_v42_performance_counters) != + V3D_V42_NUM_PERFCOUNTERS); + BUILD_BUG_ON(ARRAY_SIZE(v3d_v71_performance_counters) != + V3D_V71_NUM_PERFCOUNTERS); + BUILD_BUG_ON(V3D_MAX_COUNTERS < V3D_V42_NUM_PERFCOUNTERS); + BUILD_BUG_ON(V3D_MAX_COUNTERS < V3D_V71_NUM_PERFCOUNTERS); + BUILD_BUG_ON((V3D_MAX_COUNTERS != V3D_V42_NUM_PERFCOUNTERS) && + (V3D_MAX_COUNTERS != V3D_V71_NUM_PERFCOUNTERS)); + + if (v3d->ver >= 71) counter = &v3d_v71_performance_counters[req->counter]; - } else if (v3d->ver >= 42) { - WARN_ON(v3d->max_counters != ARRAY_SIZE(v3d_v42_performance_counters)); + else if (v3d->ver >= 42) counter = &v3d_v42_performance_counters[req->counter]; - } else { + else return -EOPNOTSUPP; - } strscpy(req->name, counter->name, sizeof(req->name)); strscpy(req->category, counter->category, sizeof(req->category)); diff --git a/drivers/gpu/drm/v3d/v3d_performance_counters.h b/drivers/gpu/drm/v3d/v3d_performance_counters.h index 72822205ebdc..131b2909522a 100644 --- a/drivers/gpu/drm/v3d/v3d_performance_counters.h +++ b/drivers/gpu/drm/v3d/v3d_performance_counters.h @@ -19,190 +19,11 @@ struct v3d_perf_counter_desc { char description[256]; }; -static const struct v3d_perf_counter_desc v3d_v71_performance_counters[] = { - {"CORE", "cycle-count", "[CORE] Cycle counter"}, - {"CORE", "core-active", "[CORE] Bin/Render/Compute active cycles"}, - {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"}, - {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"}, - {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"}, - {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"}, - {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"}, - {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"}, - {"FEP", "FEP-valid-quads", "[FEP] Valid quads"}, - {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"}, - {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"}, - {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"}, - {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"}, - {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"}, - {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"}, - {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"}, - {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"}, - {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"}, - {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"}, - {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"}, - {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"}, - {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"}, - {"TMU", "TMU-active-cycles", "[TMU] Active cycles"}, - {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"}, - {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"}, - {"TMU", "TMU-cache-x4-active-cycles", "[TMU] Cache active cycles for x4 access"}, - {"TMU", "TMU-cache-x4-stalled-cycles", "[TMU] Cache stalled cycles for x4 access"}, - {"TMU", "TMU-total-text-quads-x4-access", "[TMU] Total texture cache x4 access"}, - {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"}, - {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"}, - {"L2T", "L2T-local", "[L2T] Local mode access"}, - {"L2T", "L2T-writeback", "[L2T] Writeback"}, - {"L2T", "L2T-zero", "[L2T] Zero"}, - {"L2T", "L2T-merge", "[L2T] Merge"}, - {"L2T", "L2T-fill", "[L2T] Fill"}, - {"L2T", "L2T-stalls-no-wid", "[L2T] Stalls because no WID available"}, - {"L2T", "L2T-stalls-no-rid", "[L2T] Stalls because no RID available"}, - {"L2T", "L2T-stalls-queue-full", "[L2T] Stalls because internal queue full"}, - {"L2T", "L2T-stalls-wrightback", "[L2T] Stalls because writeback in flight"}, - {"L2T", "L2T-stalls-mem", "[L2T] Stalls because AXI blocks read"}, - {"L2T", "L2T-stalls-fill", "[L2T] Stalls because fill pending for victim cache-line"}, - {"L2T", "L2T-hitq", "[L2T] Sent request via hit queue"}, - {"L2T", "L2T-hitq-full", "[L2T] Sent request via main queue because hit queue is full"}, - {"L2T", "L2T-stalls-read-data", "[L2T] Stalls because waiting for data from SDRAM"}, - {"L2T", "L2T-TMU-read-hits", "[L2T] TMU read hits"}, - {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"}, - {"L2T", "L2T-VCD-read-hits", "[L2T] VCD read hits"}, - {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"}, - {"L2T", "L2T-SLC-read-hits", "[L2T] SLC read hits (all slices)"}, - {"L2T", "L2T-SLC-read-miss", "[L2T] SLC read misses (all slices)"}, - {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"}, - {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"}, - {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"}, - {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"}, - {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"}, - {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"}, - {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"}, - {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"}, - {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"}, - {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"}, - {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"}, - {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"}, - {"CORE", "core-memory-writes", "[CORE] Total memory writes"}, - {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"}, - {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"}, - {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"}, - {"CORE", "core-memory-reads", "[CORE] Total memory reads"}, - {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"}, - {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"}, - {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"}, - {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"}, - {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"}, - {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"}, - {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"}, - {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"}, - {"AXI", "AXI-read-trans", "[AXI] Read transaction count"}, - {"AXI", "AXI-write-trans", "[AXI] Write transaction count"}, - {"AXI", "AXI-read-wait-cycles", "[AXI] Read total wait cycles"}, - {"AXI", "AXI-write-wait-cycles", "[AXI] Write total wait cycles"}, - {"AXI", "AXI-max-outstanding-reads", "[AXI] Maximum outstanding read transactions"}, - {"AXI", "AXI-max-outstanding-writes", "[AXI] Maximum outstanding write transactions"}, - {"QPU", "QPU-wait-bubble", "[QPU] Pipeline bubble in qcycles due all threads waiting"}, - {"QPU", "QPU-ic-miss-bubble", "[QPU] Pipeline bubble in qcycles due instruction-cache miss"}, - {"QPU", "QPU-active", "[QPU] Executed shader instruction"}, - {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"}, - {"QPU", "QPU-stalls", "[QPU] Stalled qcycles executing shader instruction"}, - {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"}, - {"QPU", "QPU-stalls-TMU", "[QPU] Stalled qcycles waiting for TMU"}, - {"QPU", "QPU-stalls-TLB", "[QPU] Stalled qcycles waiting for TLB"}, - {"QPU", "QPU-stalls-VPM", "[QPU] Stalled qcycles waiting for VPM"}, - {"QPU", "QPU-stalls-uniforms", "[QPU] Stalled qcycles waiting for uniforms"}, - {"QPU", "QPU-stalls-SFU", "[QPU] Stalled qcycles waiting for SFU"}, - {"QPU", "QPU-stalls-other", "[QPU] Stalled qcycles waiting for any other reason (vary/W/Z)"}, -}; -static const struct v3d_perf_counter_desc v3d_v42_performance_counters[] = { - {"FEP", "FEP-valid-primitives-no-rendered-pixels", "[FEP] Valid primitives that result in no rendered pixels, for all rendered tiles"}, - {"FEP", "FEP-valid-primitives-rendered-pixels", "[FEP] Valid primitives for all rendered tiles (primitives may be counted in more than one tile)"}, - {"FEP", "FEP-clipped-quads", "[FEP] Early-Z/Near/Far clipped quads"}, - {"FEP", "FEP-valid-quads", "[FEP] Valid quads"}, - {"TLB", "TLB-quads-not-passing-stencil-test", "[TLB] Quads with no pixels passing the stencil test"}, - {"TLB", "TLB-quads-not-passing-z-and-stencil-test", "[TLB] Quads with no pixels passing the Z and stencil tests"}, - {"TLB", "TLB-quads-passing-z-and-stencil-test", "[TLB] Quads with any pixels passing the Z and stencil tests"}, - {"TLB", "TLB-quads-with-zero-coverage", "[TLB] Quads with all pixels having zero coverage"}, - {"TLB", "TLB-quads-with-non-zero-coverage", "[TLB] Quads with any pixels having non-zero coverage"}, - {"TLB", "TLB-quads-written-to-color-buffer", "[TLB] Quads with valid pixels written to colour buffer"}, - {"PTB", "PTB-primitives-discarded-outside-viewport", "[PTB] Primitives discarded by being outside the viewport"}, - {"PTB", "PTB-primitives-need-clipping", "[PTB] Primitives that need clipping"}, - {"PTB", "PTB-primitives-discarded-reversed", "[PTB] Primitives that are discarded because they are reversed"}, - {"QPU", "QPU-total-idle-clk-cycles", "[QPU] Total idle clock cycles for all QPUs"}, - {"QPU", "QPU-total-active-clk-cycles-vertex-coord-shading", "[QPU] Total active clock cycles for all QPUs doing vertex/coordinate/user shading (counts only when QPU is not stalled)"}, - {"QPU", "QPU-total-active-clk-cycles-fragment-shading", "[QPU] Total active clock cycles for all QPUs doing fragment shading (counts only when QPU is not stalled)"}, - {"QPU", "QPU-total-clk-cycles-executing-valid-instr", "[QPU] Total clock cycles for all QPUs executing valid instructions"}, - {"QPU", "QPU-total-clk-cycles-waiting-TMU", "[QPU] Total clock cycles for all QPUs stalled waiting for TMUs only (counter won't increment if QPU also stalling for another reason)"}, - {"QPU", "QPU-total-clk-cycles-waiting-scoreboard", "[QPU] Total clock cycles for all QPUs stalled waiting for Scoreboard only (counter won't increment if QPU also stalling for another reason)"}, - {"QPU", "QPU-total-clk-cycles-waiting-varyings", "[QPU] Total clock cycles for all QPUs stalled waiting for Varyings only (counter won't increment if QPU also stalling for another reason)"}, - {"QPU", "QPU-total-instr-cache-hit", "[QPU] Total instruction cache hits for all slices"}, - {"QPU", "QPU-total-instr-cache-miss", "[QPU] Total instruction cache misses for all slices"}, - {"QPU", "QPU-total-uniform-cache-hit", "[QPU] Total uniforms cache hits for all slices"}, - {"QPU", "QPU-total-uniform-cache-miss", "[QPU] Total uniforms cache misses for all slices"}, - {"TMU", "TMU-total-text-quads-access", "[TMU] Total texture cache accesses"}, - {"TMU", "TMU-total-text-cache-miss", "[TMU] Total texture cache misses (number of fetches from memory/L2cache)"}, - {"VPM", "VPM-total-clk-cycles-VDW-stalled", "[VPM] Total clock cycles VDW is stalled waiting for VPM access"}, - {"VPM", "VPM-total-clk-cycles-VCD-stalled", "[VPM] Total clock cycles VCD is stalled waiting for VPM access"}, - {"CLE", "CLE-bin-thread-active-cycles", "[CLE] Bin thread active cycles"}, - {"CLE", "CLE-render-thread-active-cycles", "[CLE] Render thread active cycles"}, - {"L2T", "L2T-total-cache-hit", "[L2T] Total Level 2 cache hits"}, - {"L2T", "L2T-total-cache-miss", "[L2T] Total Level 2 cache misses"}, - {"CORE", "cycle-count", "[CORE] Cycle counter"}, - {"QPU", "QPU-total-clk-cycles-waiting-vertex-coord-shading", "[QPU] Total stalled clock cycles for all QPUs doing vertex/coordinate/user shading"}, - {"QPU", "QPU-total-clk-cycles-waiting-fragment-shading", "[QPU] Total stalled clock cycles for all QPUs doing fragment shading"}, - {"PTB", "PTB-primitives-binned", "[PTB] Total primitives binned"}, - {"AXI", "AXI-writes-seen-watch-0", "[AXI] Writes seen by watch 0"}, - {"AXI", "AXI-reads-seen-watch-0", "[AXI] Reads seen by watch 0"}, - {"AXI", "AXI-writes-stalled-seen-watch-0", "[AXI] Write stalls seen by watch 0"}, - {"AXI", "AXI-reads-stalled-seen-watch-0", "[AXI] Read stalls seen by watch 0"}, - {"AXI", "AXI-write-bytes-seen-watch-0", "[AXI] Total bytes written seen by watch 0"}, - {"AXI", "AXI-read-bytes-seen-watch-0", "[AXI] Total bytes read seen by watch 0"}, - {"AXI", "AXI-writes-seen-watch-1", "[AXI] Writes seen by watch 1"}, - {"AXI", "AXI-reads-seen-watch-1", "[AXI] Reads seen by watch 1"}, - {"AXI", "AXI-writes-stalled-seen-watch-1", "[AXI] Write stalls seen by watch 1"}, - {"AXI", "AXI-reads-stalled-seen-watch-1", "[AXI] Read stalls seen by watch 1"}, - {"AXI", "AXI-write-bytes-seen-watch-1", "[AXI] Total bytes written seen by watch 1"}, - {"AXI", "AXI-read-bytes-seen-watch-1", "[AXI] Total bytes read seen by watch 1"}, - {"TLB", "TLB-partial-quads-written-to-color-buffer", "[TLB] Partial quads written to the colour buffer"}, - {"TMU", "TMU-total-config-access", "[TMU] Total config accesses"}, - {"L2T", "L2T-no-id-stalled", "[L2T] No ID stall"}, - {"L2T", "L2T-command-queue-stalled", "[L2T] Command queue full stall"}, - {"L2T", "L2T-TMU-writes", "[L2T] TMU write accesses"}, - {"TMU", "TMU-active-cycles", "[TMU] Active cycles"}, - {"TMU", "TMU-stalled-cycles", "[TMU] Stalled cycles"}, - {"CLE", "CLE-thread-active-cycles", "[CLE] Bin or render thread active cycles"}, - {"L2T", "L2T-TMU-reads", "[L2T] TMU read accesses"}, - {"L2T", "L2T-CLE-reads", "[L2T] CLE read accesses"}, - {"L2T", "L2T-VCD-reads", "[L2T] VCD read accesses"}, - {"L2T", "L2T-TMU-config-reads", "[L2T] TMU CFG read accesses"}, - {"L2T", "L2T-SLC0-reads", "[L2T] SLC0 read accesses"}, - {"L2T", "L2T-SLC1-reads", "[L2T] SLC1 read accesses"}, - {"L2T", "L2T-SLC2-reads", "[L2T] SLC2 read accesses"}, - {"L2T", "L2T-TMU-write-miss", "[L2T] TMU write misses"}, - {"L2T", "L2T-TMU-read-miss", "[L2T] TMU read misses"}, - {"L2T", "L2T-CLE-read-miss", "[L2T] CLE read misses"}, - {"L2T", "L2T-VCD-read-miss", "[L2T] VCD read misses"}, - {"L2T", "L2T-TMU-config-read-miss", "[L2T] TMU CFG read misses"}, - {"L2T", "L2T-SLC0-read-miss", "[L2T] SLC0 read misses"}, - {"L2T", "L2T-SLC1-read-miss", "[L2T] SLC1 read misses"}, - {"L2T", "L2T-SLC2-read-miss", "[L2T] SLC2 read misses"}, - {"CORE", "core-memory-writes", "[CORE] Total memory writes"}, - {"L2T", "L2T-memory-writes", "[L2T] Total memory writes"}, - {"PTB", "PTB-memory-writes", "[PTB] Total memory writes"}, - {"TLB", "TLB-memory-writes", "[TLB] Total memory writes"}, - {"CORE", "core-memory-reads", "[CORE] Total memory reads"}, - {"L2T", "L2T-memory-reads", "[L2T] Total memory reads"}, - {"PTB", "PTB-memory-reads", "[PTB] Total memory reads"}, - {"PSE", "PSE-memory-reads", "[PSE] Total memory reads"}, - {"TLB", "TLB-memory-reads", "[TLB] Total memory reads"}, - {"GMP", "GMP-memory-reads", "[GMP] Total memory reads"}, - {"PTB", "PTB-memory-words-writes", "[PTB] Total memory words written"}, - {"TLB", "TLB-memory-words-writes", "[TLB] Total memory words written"}, - {"PSE", "PSE-memory-words-reads", "[PSE] Total memory words read"}, - {"TLB", "TLB-memory-words-reads", "[TLB] Total memory words read"}, - {"TMU", "TMU-MRU-hits", "[TMU] Total MRU hits"}, - {"CORE", "compute-active-cycles", "[CORE] Compute active cycles"}, -}; +#define V3D_V42_NUM_PERFCOUNTERS (87) +#define V3D_V71_NUM_PERFCOUNTERS (93) + +/* Maximum number of performance counters supported by any version of V3D */ +#define V3D_MAX_COUNTERS (93) #endif diff --git a/include/linux/mfd/atmel-hlcdc.h b/include/linux/mfd/atmel-hlcdc.h index a186119a49b5..80d675a03b39 100644 --- a/include/linux/mfd/atmel-hlcdc.h +++ b/include/linux/mfd/atmel-hlcdc.h @@ -22,6 +22,8 @@ #define ATMEL_HLCDC_DITHER BIT(6) #define ATMEL_HLCDC_DISPDLY BIT(7) #define ATMEL_HLCDC_MODE_MASK GENMASK(9, 8) +#define ATMEL_XLCDC_MODE_MASK GENMASK(10, 8) +#define ATMEL_XLCDC_DPI BIT(11) #define ATMEL_HLCDC_PP BIT(10) #define ATMEL_HLCDC_VSPSU BIT(12) #define ATMEL_HLCDC_VSPHO BIT(13) @@ -34,6 +36,12 @@ #define ATMEL_HLCDC_IDR 0x30 #define ATMEL_HLCDC_IMR 0x34 #define ATMEL_HLCDC_ISR 0x38 +#define ATMEL_XLCDC_ATTRE 0x3c + +#define ATMEL_XLCDC_BASE_UPDATE BIT(0) +#define ATMEL_XLCDC_OVR1_UPDATE BIT(1) +#define ATMEL_XLCDC_OVR3_UPDATE BIT(2) +#define ATMEL_XLCDC_HEO_UPDATE BIT(3) #define ATMEL_HLCDC_CLKPOL BIT(0) #define ATMEL_HLCDC_CLKSEL BIT(2) @@ -48,6 +56,8 @@ #define ATMEL_HLCDC_DISP BIT(2) #define ATMEL_HLCDC_PWM BIT(3) #define ATMEL_HLCDC_SIP BIT(4) +#define ATMEL_XLCDC_SD BIT(5) +#define ATMEL_XLCDC_CM BIT(6) #define ATMEL_HLCDC_SOF BIT(0) #define ATMEL_HLCDC_SYNCDIS BIT(1) diff --git a/include/uapi/linux/dma-heap.h b/include/uapi/linux/dma-heap.h index 6f84fa08e074..a4cf716a49fa 100644 --- a/include/uapi/linux/dma-heap.h +++ b/include/uapi/linux/dma-heap.h @@ -19,7 +19,7 @@ #define DMA_HEAP_VALID_FD_FLAGS (O_CLOEXEC | O_ACCMODE) /* Currently no heap flags */ -#define DMA_HEAP_VALID_HEAP_FLAGS (0) +#define DMA_HEAP_VALID_HEAP_FLAGS (0ULL) /** * struct dma_heap_allocation_data - metadata passed from userspace for |