diff options
Diffstat (limited to 'drivers/gpu')
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_crtc.c | 162 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_dpi.c | 14 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.c | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_drv.h | 7 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_hdmi.c | 13 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_plane.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_regs.h | 22 |
7 files changed, 211 insertions, 22 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c index c82d468d178b..8fc2b731b59a 100644 --- a/drivers/gpu/drm/vc4/vc4_crtc.c +++ b/drivers/gpu/drm/vc4/vc4_crtc.c | |||
| @@ -46,12 +46,17 @@ struct vc4_crtc { | |||
| 46 | const struct vc4_crtc_data *data; | 46 | const struct vc4_crtc_data *data; |
| 47 | void __iomem *regs; | 47 | void __iomem *regs; |
| 48 | 48 | ||
| 49 | /* Timestamp at start of vblank irq - unaffected by lock delays. */ | ||
| 50 | ktime_t t_vblank; | ||
| 51 | |||
| 49 | /* Which HVS channel we're using for our CRTC. */ | 52 | /* Which HVS channel we're using for our CRTC. */ |
| 50 | int channel; | 53 | int channel; |
| 51 | 54 | ||
| 52 | u8 lut_r[256]; | 55 | u8 lut_r[256]; |
| 53 | u8 lut_g[256]; | 56 | u8 lut_g[256]; |
| 54 | u8 lut_b[256]; | 57 | u8 lut_b[256]; |
| 58 | /* Size in pixels of the COB memory allocated to this CRTC. */ | ||
| 59 | u32 cob_size; | ||
| 55 | 60 | ||
| 56 | struct drm_pending_vblank_event *event; | 61 | struct drm_pending_vblank_event *event; |
| 57 | }; | 62 | }; |
| @@ -146,6 +151,144 @@ int vc4_crtc_debugfs_regs(struct seq_file *m, void *unused) | |||
| 146 | } | 151 | } |
| 147 | #endif | 152 | #endif |
| 148 | 153 | ||
| 154 | int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | ||
| 155 | unsigned int flags, int *vpos, int *hpos, | ||
| 156 | ktime_t *stime, ktime_t *etime, | ||
| 157 | const struct drm_display_mode *mode) | ||
| 158 | { | ||
| 159 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 160 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | ||
| 161 | u32 val; | ||
| 162 | int fifo_lines; | ||
| 163 | int vblank_lines; | ||
| 164 | int ret = 0; | ||
| 165 | |||
| 166 | /* | ||
| 167 | * XXX Doesn't work well in interlaced mode yet, partially due | ||
| 168 | * to problems in vc4 kms or drm core interlaced mode handling, | ||
| 169 | * so disable for now in interlaced mode. | ||
| 170 | */ | ||
| 171 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 172 | return ret; | ||
| 173 | |||
| 174 | /* preempt_disable_rt() should go right here in PREEMPT_RT patchset. */ | ||
| 175 | |||
| 176 | /* Get optional system timestamp before query. */ | ||
| 177 | if (stime) | ||
| 178 | *stime = ktime_get(); | ||
| 179 | |||
| 180 | /* | ||
| 181 | * Read vertical scanline which is currently composed for our | ||
| 182 | * pixelvalve by the HVS, and also the scaler status. | ||
| 183 | */ | ||
| 184 | val = HVS_READ(SCALER_DISPSTATX(vc4_crtc->channel)); | ||
| 185 | |||
| 186 | /* Get optional system timestamp after query. */ | ||
| 187 | if (etime) | ||
| 188 | *etime = ktime_get(); | ||
| 189 | |||
| 190 | /* preempt_enable_rt() should go right here in PREEMPT_RT patchset. */ | ||
| 191 | |||
| 192 | /* Vertical position of hvs composed scanline. */ | ||
| 193 | *vpos = VC4_GET_FIELD(val, SCALER_DISPSTATX_LINE); | ||
| 194 | |||
| 195 | /* No hpos info available. */ | ||
| 196 | if (hpos) | ||
| 197 | *hpos = 0; | ||
| 198 | |||
| 199 | /* This is the offset we need for translating hvs -> pv scanout pos. */ | ||
| 200 | fifo_lines = vc4_crtc->cob_size / mode->crtc_hdisplay; | ||
| 201 | |||
| 202 | if (fifo_lines > 0) | ||
| 203 | ret |= DRM_SCANOUTPOS_VALID; | ||
| 204 | |||
| 205 | /* HVS more than fifo_lines into frame for compositing? */ | ||
| 206 | if (*vpos > fifo_lines) { | ||
| 207 | /* | ||
| 208 | * We are in active scanout and can get some meaningful results | ||
| 209 | * from HVS. The actual PV scanout can not trail behind more | ||
| 210 | * than fifo_lines as that is the fifo's capacity. Assume that | ||
| 211 | * in active scanout the HVS and PV work in lockstep wrt. HVS | ||
| 212 | * refilling the fifo and PV consuming from the fifo, ie. | ||
| 213 | * whenever the PV consumes and frees up a scanline in the | ||
| 214 | * fifo, the HVS will immediately refill it, therefore | ||
| 215 | * incrementing vpos. Therefore we choose HVS read position - | ||
| 216 | * fifo size in scanlines as a estimate of the real scanout | ||
| 217 | * position of the PV. | ||
| 218 | */ | ||
| 219 | *vpos -= fifo_lines + 1; | ||
| 220 | if (mode->flags & DRM_MODE_FLAG_INTERLACE) | ||
| 221 | *vpos /= 2; | ||
| 222 | |||
| 223 | ret |= DRM_SCANOUTPOS_ACCURATE; | ||
| 224 | return ret; | ||
| 225 | } | ||
| 226 | |||
| 227 | /* | ||
| 228 | * Less: This happens when we are in vblank and the HVS, after getting | ||
| 229 | * the VSTART restart signal from the PV, just started refilling its | ||
| 230 | * fifo with new lines from the top-most lines of the new framebuffers. | ||
| 231 | * The PV does not scan out in vblank, so does not remove lines from | ||
| 232 | * the fifo, so the fifo will be full quickly and the HVS has to pause. | ||
| 233 | * We can't get meaningful readings wrt. scanline position of the PV | ||
| 234 | * and need to make things up in a approximative but consistent way. | ||
| 235 | */ | ||
| 236 | ret |= DRM_SCANOUTPOS_IN_VBLANK; | ||
| 237 | vblank_lines = mode->crtc_vtotal - mode->crtc_vdisplay; | ||
| 238 | |||
| 239 | if (flags & DRM_CALLED_FROM_VBLIRQ) { | ||
| 240 | /* | ||
| 241 | * Assume the irq handler got called close to first | ||
| 242 | * line of vblank, so PV has about a full vblank | ||
| 243 | * scanlines to go, and as a base timestamp use the | ||
| 244 | * one taken at entry into vblank irq handler, so it | ||
| 245 | * is not affected by random delays due to lock | ||
| 246 | * contention on event_lock or vblank_time lock in | ||
| 247 | * the core. | ||
| 248 | */ | ||
| 249 | *vpos = -vblank_lines; | ||
| 250 | |||
| 251 | if (stime) | ||
| 252 | *stime = vc4_crtc->t_vblank; | ||
| 253 | if (etime) | ||
| 254 | *etime = vc4_crtc->t_vblank; | ||
| 255 | |||
| 256 | /* | ||
| 257 | * If the HVS fifo is not yet full then we know for certain | ||
| 258 | * we are at the very beginning of vblank, as the hvs just | ||
| 259 | * started refilling, and the stime and etime timestamps | ||
| 260 | * truly correspond to start of vblank. | ||
| 261 | */ | ||
| 262 | if ((val & SCALER_DISPSTATX_FULL) != SCALER_DISPSTATX_FULL) | ||
| 263 | ret |= DRM_SCANOUTPOS_ACCURATE; | ||
| 264 | } else { | ||
| 265 | /* | ||
| 266 | * No clue where we are inside vblank. Return a vpos of zero, | ||
| 267 | * which will cause calling code to just return the etime | ||
| 268 | * timestamp uncorrected. At least this is no worse than the | ||
| 269 | * standard fallback. | ||
| 270 | */ | ||
| 271 | *vpos = 0; | ||
| 272 | } | ||
| 273 | |||
| 274 | return ret; | ||
| 275 | } | ||
| 276 | |||
| 277 | int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, | ||
| 278 | int *max_error, struct timeval *vblank_time, | ||
| 279 | unsigned flags) | ||
| 280 | { | ||
| 281 | struct vc4_dev *vc4 = to_vc4_dev(dev); | ||
| 282 | struct vc4_crtc *vc4_crtc = vc4->crtc[crtc_id]; | ||
| 283 | struct drm_crtc *crtc = &vc4_crtc->base; | ||
| 284 | struct drm_crtc_state *state = crtc->state; | ||
| 285 | |||
| 286 | /* Helper routine in DRM core does all the work: */ | ||
| 287 | return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc_id, max_error, | ||
| 288 | vblank_time, flags, | ||
| 289 | &state->adjusted_mode); | ||
| 290 | } | ||
| 291 | |||
| 149 | static void vc4_crtc_destroy(struct drm_crtc *crtc) | 292 | static void vc4_crtc_destroy(struct drm_crtc *crtc) |
| 150 | { | 293 | { |
| 151 | drm_crtc_cleanup(crtc); | 294 | drm_crtc_cleanup(crtc); |
| @@ -519,6 +662,7 @@ static irqreturn_t vc4_crtc_irq_handler(int irq, void *data) | |||
| 519 | irqreturn_t ret = IRQ_NONE; | 662 | irqreturn_t ret = IRQ_NONE; |
| 520 | 663 | ||
| 521 | if (stat & PV_INT_VFP_START) { | 664 | if (stat & PV_INT_VFP_START) { |
| 665 | vc4_crtc->t_vblank = ktime_get(); | ||
| 522 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); | 666 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); |
| 523 | drm_crtc_handle_vblank(&vc4_crtc->base); | 667 | drm_crtc_handle_vblank(&vc4_crtc->base); |
| 524 | vc4_crtc_handle_page_flip(vc4_crtc); | 668 | vc4_crtc_handle_page_flip(vc4_crtc); |
| @@ -723,6 +867,22 @@ static void vc4_set_crtc_possible_masks(struct drm_device *drm, | |||
| 723 | } | 867 | } |
| 724 | } | 868 | } |
| 725 | 869 | ||
| 870 | static void | ||
| 871 | vc4_crtc_get_cob_allocation(struct vc4_crtc *vc4_crtc) | ||
| 872 | { | ||
| 873 | struct drm_device *drm = vc4_crtc->base.dev; | ||
| 874 | struct vc4_dev *vc4 = to_vc4_dev(drm); | ||
| 875 | u32 dispbase = HVS_READ(SCALER_DISPBASEX(vc4_crtc->channel)); | ||
| 876 | /* Top/base are supposed to be 4-pixel aligned, but the | ||
| 877 | * Raspberry Pi firmware fills the low bits (which are | ||
| 878 | * presumably ignored). | ||
| 879 | */ | ||
| 880 | u32 top = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_TOP) & ~3; | ||
| 881 | u32 base = VC4_GET_FIELD(dispbase, SCALER_DISPBASEX_BASE) & ~3; | ||
| 882 | |||
| 883 | vc4_crtc->cob_size = top - base + 4; | ||
| 884 | } | ||
| 885 | |||
| 726 | static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) | 886 | static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) |
| 727 | { | 887 | { |
| 728 | struct platform_device *pdev = to_platform_device(dev); | 888 | struct platform_device *pdev = to_platform_device(dev); |
| @@ -799,6 +959,8 @@ static int vc4_crtc_bind(struct device *dev, struct device *master, void *data) | |||
| 799 | crtc->cursor = cursor_plane; | 959 | crtc->cursor = cursor_plane; |
| 800 | } | 960 | } |
| 801 | 961 | ||
| 962 | vc4_crtc_get_cob_allocation(vc4_crtc); | ||
| 963 | |||
| 802 | CRTC_WRITE(PV_INTEN, 0); | 964 | CRTC_WRITE(PV_INTEN, 0); |
| 803 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); | 965 | CRTC_WRITE(PV_INTSTAT, PV_INT_VFP_START); |
| 804 | ret = devm_request_irq(dev, platform_get_irq(pdev, 0), | 966 | ret = devm_request_irq(dev, platform_get_irq(pdev, 0), |
diff --git a/drivers/gpu/drm/vc4/vc4_dpi.c b/drivers/gpu/drm/vc4/vc4_dpi.c index dba1114297e4..275fedbdbd9e 100644 --- a/drivers/gpu/drm/vc4/vc4_dpi.c +++ b/drivers/gpu/drm/vc4/vc4_dpi.c | |||
| @@ -227,14 +227,12 @@ static struct drm_connector *vc4_dpi_connector_init(struct drm_device *dev, | |||
| 227 | { | 227 | { |
| 228 | struct drm_connector *connector = NULL; | 228 | struct drm_connector *connector = NULL; |
| 229 | struct vc4_dpi_connector *dpi_connector; | 229 | struct vc4_dpi_connector *dpi_connector; |
| 230 | int ret = 0; | ||
| 231 | 230 | ||
| 232 | dpi_connector = devm_kzalloc(dev->dev, sizeof(*dpi_connector), | 231 | dpi_connector = devm_kzalloc(dev->dev, sizeof(*dpi_connector), |
| 233 | GFP_KERNEL); | 232 | GFP_KERNEL); |
| 234 | if (!dpi_connector) { | 233 | if (!dpi_connector) |
| 235 | ret = -ENOMEM; | 234 | return ERR_PTR(-ENOMEM); |
| 236 | goto fail; | 235 | |
| 237 | } | ||
| 238 | connector = &dpi_connector->base; | 236 | connector = &dpi_connector->base; |
| 239 | 237 | ||
| 240 | dpi_connector->encoder = dpi->encoder; | 238 | dpi_connector->encoder = dpi->encoder; |
| @@ -251,12 +249,6 @@ static struct drm_connector *vc4_dpi_connector_init(struct drm_device *dev, | |||
| 251 | drm_mode_connector_attach_encoder(connector, dpi->encoder); | 249 | drm_mode_connector_attach_encoder(connector, dpi->encoder); |
| 252 | 250 | ||
| 253 | return connector; | 251 | return connector; |
| 254 | |||
| 255 | fail: | ||
| 256 | if (connector) | ||
| 257 | vc4_dpi_connector_destroy(connector); | ||
| 258 | |||
| 259 | return ERR_PTR(ret); | ||
| 260 | } | 252 | } |
| 261 | 253 | ||
| 262 | static const struct drm_encoder_funcs vc4_dpi_encoder_funcs = { | 254 | static const struct drm_encoder_funcs vc4_dpi_encoder_funcs = { |
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c index 54d0471243dd..9bb98a3cdc4f 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.c +++ b/drivers/gpu/drm/vc4/vc4_drv.c | |||
| @@ -92,6 +92,8 @@ static struct drm_driver vc4_drm_driver = { | |||
| 92 | .enable_vblank = vc4_enable_vblank, | 92 | .enable_vblank = vc4_enable_vblank, |
| 93 | .disable_vblank = vc4_disable_vblank, | 93 | .disable_vblank = vc4_disable_vblank, |
| 94 | .get_vblank_counter = drm_vblank_no_hw_counter, | 94 | .get_vblank_counter = drm_vblank_no_hw_counter, |
| 95 | .get_scanout_position = vc4_crtc_get_scanoutpos, | ||
| 96 | .get_vblank_timestamp = vc4_crtc_get_vblank_timestamp, | ||
| 95 | 97 | ||
| 96 | #if defined(CONFIG_DEBUG_FS) | 98 | #if defined(CONFIG_DEBUG_FS) |
| 97 | .debugfs_init = vc4_debugfs_init, | 99 | .debugfs_init = vc4_debugfs_init, |
| @@ -195,8 +197,6 @@ static int vc4_drm_bind(struct device *dev) | |||
| 195 | vc4_bo_cache_init(drm); | 197 | vc4_bo_cache_init(drm); |
| 196 | 198 | ||
| 197 | drm_mode_config_init(drm); | 199 | drm_mode_config_init(drm); |
| 198 | if (ret) | ||
| 199 | goto unref; | ||
| 200 | 200 | ||
| 201 | vc4_gem_init(drm); | 201 | vc4_gem_init(drm); |
| 202 | 202 | ||
| @@ -218,7 +218,6 @@ unbind_all: | |||
| 218 | component_unbind_all(dev, drm); | 218 | component_unbind_all(dev, drm); |
| 219 | gem_destroy: | 219 | gem_destroy: |
| 220 | vc4_gem_destroy(drm); | 220 | vc4_gem_destroy(drm); |
| 221 | unref: | ||
| 222 | drm_dev_unref(drm); | 221 | drm_dev_unref(drm); |
| 223 | vc4_bo_cache_destroy(drm); | 222 | vc4_bo_cache_destroy(drm); |
| 224 | return ret; | 223 | return ret; |
| @@ -246,8 +245,8 @@ static const struct component_master_ops vc4_drm_ops = { | |||
| 246 | static struct platform_driver *const component_drivers[] = { | 245 | static struct platform_driver *const component_drivers[] = { |
| 247 | &vc4_hdmi_driver, | 246 | &vc4_hdmi_driver, |
| 248 | &vc4_dpi_driver, | 247 | &vc4_dpi_driver, |
| 249 | &vc4_crtc_driver, | ||
| 250 | &vc4_hvs_driver, | 248 | &vc4_hvs_driver, |
| 249 | &vc4_crtc_driver, | ||
| 251 | &vc4_v3d_driver, | 250 | &vc4_v3d_driver, |
| 252 | }; | 251 | }; |
| 253 | 252 | ||
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h index c799baabc008..8e3b84e758ac 100644 --- a/drivers/gpu/drm/vc4/vc4_drv.h +++ b/drivers/gpu/drm/vc4/vc4_drv.h | |||
| @@ -415,6 +415,13 @@ extern struct platform_driver vc4_crtc_driver; | |||
| 415 | int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id); | 415 | int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id); |
| 416 | void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id); | 416 | void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id); |
| 417 | int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); | 417 | int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); |
| 418 | int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, | ||
| 419 | unsigned int flags, int *vpos, int *hpos, | ||
| 420 | ktime_t *stime, ktime_t *etime, | ||
| 421 | const struct drm_display_mode *mode); | ||
| 422 | int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, | ||
| 423 | int *max_error, struct timeval *vblank_time, | ||
| 424 | unsigned flags); | ||
| 418 | 425 | ||
| 419 | /* vc4_debugfs.c */ | 426 | /* vc4_debugfs.c */ |
| 420 | int vc4_debugfs_init(struct drm_minor *minor); | 427 | int vc4_debugfs_init(struct drm_minor *minor); |
diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c index 68df91c3f860..4452f3631cac 100644 --- a/drivers/gpu/drm/vc4/vc4_hdmi.c +++ b/drivers/gpu/drm/vc4/vc4_hdmi.c | |||
| @@ -456,12 +456,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 456 | if (IS_ERR(hdmi->hd_regs)) | 456 | if (IS_ERR(hdmi->hd_regs)) |
| 457 | return PTR_ERR(hdmi->hd_regs); | 457 | return PTR_ERR(hdmi->hd_regs); |
| 458 | 458 | ||
| 459 | ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); | ||
| 460 | if (!ddc_node) { | ||
| 461 | DRM_ERROR("Failed to find ddc node in device tree\n"); | ||
| 462 | return -ENODEV; | ||
| 463 | } | ||
| 464 | |||
| 465 | hdmi->pixel_clock = devm_clk_get(dev, "pixel"); | 459 | hdmi->pixel_clock = devm_clk_get(dev, "pixel"); |
| 466 | if (IS_ERR(hdmi->pixel_clock)) { | 460 | if (IS_ERR(hdmi->pixel_clock)) { |
| 467 | DRM_ERROR("Failed to get pixel clock\n"); | 461 | DRM_ERROR("Failed to get pixel clock\n"); |
| @@ -473,7 +467,14 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) | |||
| 473 | return PTR_ERR(hdmi->hsm_clock); | 467 | return PTR_ERR(hdmi->hsm_clock); |
| 474 | } | 468 | } |
| 475 | 469 | ||
| 470 | ddc_node = of_parse_phandle(dev->of_node, "ddc", 0); | ||
| 471 | if (!ddc_node) { | ||
| 472 | DRM_ERROR("Failed to find ddc node in device tree\n"); | ||
| 473 | return -ENODEV; | ||
| 474 | } | ||
| 475 | |||
| 476 | hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); | 476 | hdmi->ddc = of_find_i2c_adapter_by_node(ddc_node); |
| 477 | of_node_put(ddc_node); | ||
| 477 | if (!hdmi->ddc) { | 478 | if (!hdmi->ddc) { |
| 478 | DRM_DEBUG("Failed to get ddc i2c adapter by node\n"); | 479 | DRM_DEBUG("Failed to get ddc i2c adapter by node\n"); |
| 479 | return -EPROBE_DEFER; | 480 | return -EPROBE_DEFER; |
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c index 5d2c3d9fd17a..29e4b400e25e 100644 --- a/drivers/gpu/drm/vc4/vc4_plane.c +++ b/drivers/gpu/drm/vc4/vc4_plane.c | |||
| @@ -94,6 +94,14 @@ static const struct hvs_format { | |||
| 94 | .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, | 94 | .pixel_order = HVS_PIXEL_ORDER_ABGR, .has_alpha = true, |
| 95 | }, | 95 | }, |
| 96 | { | 96 | { |
| 97 | .drm = DRM_FORMAT_ABGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888, | ||
| 98 | .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = true, | ||
| 99 | }, | ||
| 100 | { | ||
| 101 | .drm = DRM_FORMAT_XBGR8888, .hvs = HVS_PIXEL_FORMAT_RGBA8888, | ||
| 102 | .pixel_order = HVS_PIXEL_ORDER_ARGB, .has_alpha = false, | ||
| 103 | }, | ||
| 104 | { | ||
| 97 | .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, | 105 | .drm = DRM_FORMAT_RGB565, .hvs = HVS_PIXEL_FORMAT_RGB565, |
| 98 | .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, | 106 | .pixel_order = HVS_PIXEL_ORDER_XRGB, .has_alpha = false, |
| 99 | }, | 107 | }, |
diff --git a/drivers/gpu/drm/vc4/vc4_regs.h b/drivers/gpu/drm/vc4/vc4_regs.h index f99eece4cc97..160942a9180e 100644 --- a/drivers/gpu/drm/vc4/vc4_regs.h +++ b/drivers/gpu/drm/vc4/vc4_regs.h | |||
| @@ -366,7 +366,6 @@ | |||
| 366 | # define SCALER_DISPBKGND_FILL BIT(24) | 366 | # define SCALER_DISPBKGND_FILL BIT(24) |
| 367 | 367 | ||
| 368 | #define SCALER_DISPSTAT0 0x00000048 | 368 | #define SCALER_DISPSTAT0 0x00000048 |
| 369 | #define SCALER_DISPBASE0 0x0000004c | ||
| 370 | # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) | 369 | # define SCALER_DISPSTATX_MODE_MASK VC4_MASK(31, 30) |
| 371 | # define SCALER_DISPSTATX_MODE_SHIFT 30 | 370 | # define SCALER_DISPSTATX_MODE_SHIFT 30 |
| 372 | # define SCALER_DISPSTATX_MODE_DISABLED 0 | 371 | # define SCALER_DISPSTATX_MODE_DISABLED 0 |
| @@ -375,6 +374,24 @@ | |||
| 375 | # define SCALER_DISPSTATX_MODE_EOF 3 | 374 | # define SCALER_DISPSTATX_MODE_EOF 3 |
| 376 | # define SCALER_DISPSTATX_FULL BIT(29) | 375 | # define SCALER_DISPSTATX_FULL BIT(29) |
| 377 | # define SCALER_DISPSTATX_EMPTY BIT(28) | 376 | # define SCALER_DISPSTATX_EMPTY BIT(28) |
| 377 | # define SCALER_DISPSTATX_FRAME_COUNT_MASK VC4_MASK(17, 12) | ||
| 378 | # define SCALER_DISPSTATX_FRAME_COUNT_SHIFT 12 | ||
| 379 | # define SCALER_DISPSTATX_LINE_MASK VC4_MASK(11, 0) | ||
| 380 | # define SCALER_DISPSTATX_LINE_SHIFT 0 | ||
| 381 | |||
| 382 | #define SCALER_DISPBASE0 0x0000004c | ||
| 383 | /* Last pixel in the COB (display FIFO memory) allocated to this HVS | ||
| 384 | * channel. Must be 4-pixel aligned (and thus 4 pixels less than the | ||
| 385 | * next COB base). | ||
| 386 | */ | ||
| 387 | # define SCALER_DISPBASEX_TOP_MASK VC4_MASK(31, 16) | ||
| 388 | # define SCALER_DISPBASEX_TOP_SHIFT 16 | ||
| 389 | /* First pixel in the COB (display FIFO memory) allocated to this HVS | ||
| 390 | * channel. Must be 4-pixel aligned. | ||
| 391 | */ | ||
| 392 | # define SCALER_DISPBASEX_BASE_MASK VC4_MASK(15, 0) | ||
| 393 | # define SCALER_DISPBASEX_BASE_SHIFT 0 | ||
| 394 | |||
| 378 | #define SCALER_DISPCTRL1 0x00000050 | 395 | #define SCALER_DISPCTRL1 0x00000050 |
| 379 | #define SCALER_DISPBKGND1 0x00000054 | 396 | #define SCALER_DISPBKGND1 0x00000054 |
| 380 | #define SCALER_DISPBKGNDX(x) (SCALER_DISPBKGND0 + \ | 397 | #define SCALER_DISPBKGNDX(x) (SCALER_DISPBKGND0 + \ |
| @@ -385,6 +402,9 @@ | |||
| 385 | (x) * (SCALER_DISPSTAT1 - \ | 402 | (x) * (SCALER_DISPSTAT1 - \ |
| 386 | SCALER_DISPSTAT0)) | 403 | SCALER_DISPSTAT0)) |
| 387 | #define SCALER_DISPBASE1 0x0000005c | 404 | #define SCALER_DISPBASE1 0x0000005c |
| 405 | #define SCALER_DISPBASEX(x) (SCALER_DISPBASE0 + \ | ||
| 406 | (x) * (SCALER_DISPBASE1 - \ | ||
| 407 | SCALER_DISPBASE0)) | ||
| 388 | #define SCALER_DISPCTRL2 0x00000060 | 408 | #define SCALER_DISPCTRL2 0x00000060 |
| 389 | #define SCALER_DISPCTRLX(x) (SCALER_DISPCTRL0 + \ | 409 | #define SCALER_DISPCTRLX(x) (SCALER_DISPCTRL0 + \ |
| 390 | (x) * (SCALER_DISPCTRL1 - \ | 410 | (x) * (SCALER_DISPCTRL1 - \ |
