diff options
Diffstat (limited to 'drivers/gpu/drm/tiny/repaper.c')
| -rw-r--r-- | drivers/gpu/drm/tiny/repaper.c | 110 |
1 files changed, 40 insertions, 70 deletions
diff --git a/drivers/gpu/drm/tiny/repaper.c b/drivers/gpu/drm/tiny/repaper.c index 2cee07a2e00b..c8270591afc7 100644 --- a/drivers/gpu/drm/tiny/repaper.c +++ b/drivers/gpu/drm/tiny/repaper.c @@ -14,7 +14,6 @@ */ #include <linux/delay.h> -#include <linux/dma-buf.h> #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/property.h> @@ -22,19 +21,22 @@ #include <linux/spi/spi.h> #include <linux/thermal.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic_helper.h> #include <drm/drm_connector.h> #include <drm/drm_damage_helper.h> #include <drm/drm_drv.h> -#include <drm/drm_fb_cma_helper.h> -#include <drm/drm_fb_helper.h> +#include <drm/drm_fb_dma_helper.h> +#include <drm/drm_fbdev_dma.h> #include <drm/drm_format_helper.h> +#include <drm/drm_framebuffer.h> #include <drm/drm_gem_atomic_helper.h> -#include <drm/drm_gem_cma_helper.h> +#include <drm/drm_gem_dma_helper.h> #include <drm/drm_gem_framebuffer_helper.h> #include <drm/drm_managed.h> #include <drm/drm_modes.h> #include <drm/drm_rect.h> +#include <drm/drm_print.h> #include <drm/drm_probe_helper.h> #include <drm/drm_simple_kms_helper.h> @@ -455,7 +457,7 @@ static void repaper_frame_fixed_repeat(struct repaper_epd *epd, u8 fixed_value, enum repaper_stage stage) { u64 start = local_clock(); - u64 end = start + (epd->factored_stage_time * 1000 * 1000); + u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000); do { repaper_frame_fixed(epd, fixed_value, stage); @@ -466,7 +468,7 @@ static void repaper_frame_data_repeat(struct repaper_epd *epd, const u8 *image, const u8 *mask, enum repaper_stage stage) { u64 start = local_clock(); - u64 end = start + (epd->factored_stage_time * 1000 * 1000); + u64 end = start + ((u64)epd->factored_stage_time * 1000 * 1000); do { repaper_frame_data(epd, image, mask, stage); @@ -509,31 +511,12 @@ static void repaper_get_temperature(struct repaper_epd *epd) epd->factored_stage_time = epd->stage_time * factor10x / 10; } -static void repaper_gray8_to_mono_reversed(u8 *buf, u32 width, u32 height) +static int repaper_fb_dirty(struct drm_framebuffer *fb, const struct iosys_map *vmap, + struct drm_format_conv_state *fmtcnv_state) { - u8 *gray8 = buf, *mono = buf; - int y, xb, i; - - for (y = 0; y < height; y++) - for (xb = 0; xb < width / 8; xb++) { - u8 byte = 0x00; - - for (i = 0; i < 8; i++) { - int x = xb * 8 + i; - - byte >>= 1; - if (gray8[y * width + x] >> 7) - byte |= BIT(7); - } - *mono++ = byte; - } -} - -static int repaper_fb_dirty(struct drm_framebuffer *fb) -{ - struct drm_gem_cma_object *cma_obj = drm_fb_cma_get_gem_obj(fb, 0); - struct dma_buf_attachment *import_attach = cma_obj->base.import_attach; struct repaper_epd *epd = drm_to_epd(fb->dev); + unsigned int dst_pitch = 0; + struct iosys_map dst; struct drm_rect clip; int idx, ret = 0; u8 *buf = NULL; @@ -552,29 +535,20 @@ static int repaper_fb_dirty(struct drm_framebuffer *fb) DRM_DEBUG("Flushing [FB:%d] st=%ums\n", fb->base.id, epd->factored_stage_time); - buf = kmalloc_array(fb->width, fb->height, GFP_KERNEL); + buf = kmalloc(fb->width * fb->height / 8, GFP_KERNEL); if (!buf) { ret = -ENOMEM; goto out_exit; } - if (import_attach) { - ret = dma_buf_begin_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (ret) - goto out_free; - } - - drm_fb_xrgb8888_to_gray8(buf, cma_obj->vaddr, fb, &clip); + ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); + if (ret) + goto out_free; - if (import_attach) { - ret = dma_buf_end_cpu_access(import_attach->dmabuf, - DMA_FROM_DEVICE); - if (ret) - goto out_free; - } + iosys_map_set_vaddr(&dst, buf); + drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, &clip, fmtcnv_state); - repaper_gray8_to_mono_reversed(buf, fb->width, fb->height); + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); if (epd->partial) { repaper_frame_data_repeat(epd, buf, epd->current_frame, @@ -648,6 +622,15 @@ static void power_off(struct repaper_epd *epd) gpiod_set_value_cansleep(epd->discharge, 0); } +static enum drm_mode_status repaper_pipe_mode_valid(struct drm_simple_display_pipe *pipe, + const struct drm_display_mode *mode) +{ + struct drm_crtc *crtc = &pipe->crtc; + struct repaper_epd *epd = drm_to_epd(crtc->dev); + + return drm_crtc_helper_mode_valid_fixed(crtc, mode, epd->mode); +} + static void repaper_pipe_enable(struct drm_simple_display_pipe *pipe, struct drm_crtc_state *crtc_state, struct drm_plane_state *plane_state) @@ -848,41 +831,30 @@ static void repaper_pipe_update(struct drm_simple_display_pipe *pipe, struct drm_plane_state *old_state) { struct drm_plane_state *state = pipe->plane.state; + struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state); struct drm_rect rect; if (!pipe->crtc.state->active) return; if (drm_atomic_helper_damage_merged(old_state, state, &rect)) - repaper_fb_dirty(state->fb); + repaper_fb_dirty(state->fb, shadow_plane_state->data, + &shadow_plane_state->fmtcnv_state); } static const struct drm_simple_display_pipe_funcs repaper_pipe_funcs = { + .mode_valid = repaper_pipe_mode_valid, .enable = repaper_pipe_enable, .disable = repaper_pipe_disable, .update = repaper_pipe_update, - .prepare_fb = drm_gem_simple_display_pipe_prepare_fb, + DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS, }; static int repaper_connector_get_modes(struct drm_connector *connector) { struct repaper_epd *epd = drm_to_epd(connector->dev); - struct drm_display_mode *mode; - mode = drm_mode_duplicate(connector->dev, epd->mode); - if (!mode) { - DRM_ERROR("Failed to duplicate mode\n"); - return 0; - } - - drm_mode_set_name(mode); - mode->type |= DRM_MODE_TYPE_PREFERRED; - drm_mode_probed_add(connector, mode); - - connector->display_info.width_mm = mode->width_mm; - connector->display_info.height_mm = mode->height_mm; - - return 1; + return drm_connector_helper_get_modes_fixed(connector, epd->mode); } static const struct drm_connector_helper_funcs repaper_connector_hfuncs = { @@ -935,15 +907,15 @@ static const struct drm_display_mode repaper_e2271cs021_mode = { static const u8 repaper_e2271cs021_cs[] = { 0x00, 0x00, 0x00, 0x7f, 0xff, 0xfe, 0x00, 0x00 }; -DEFINE_DRM_GEM_CMA_FOPS(repaper_fops); +DEFINE_DRM_GEM_DMA_FOPS(repaper_fops); static const struct drm_driver repaper_driver = { .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_ATOMIC, .fops = &repaper_fops, - DRM_GEM_CMA_DRIVER_OPS_VMAP, + DRM_GEM_DMA_DRIVER_OPS_VMAP, + DRM_FBDEV_DMA_DRIVER_OPS, .name = "repaper", .desc = "Pervasive Displays RePaper e-ink panels", - .date = "20170405", .major = 1, .minor = 0, }; @@ -981,7 +953,7 @@ static int repaper_probe(struct spi_device *spi) match = device_get_match_data(dev); if (match) { - model = (enum repaper_model)match; + model = (enum repaper_model)(uintptr_t)match; } else { spi_id = spi_get_device_id(spi); model = (enum repaper_model)spi_id->driver_data; @@ -1146,19 +1118,17 @@ static int repaper_probe(struct spi_device *spi) DRM_DEBUG_DRIVER("SPI speed: %uMHz\n", spi->max_speed_hz / 1000000); - drm_fbdev_generic_setup(drm, 0); + drm_client_setup(drm, NULL); return 0; } -static int repaper_remove(struct spi_device *spi) +static void repaper_remove(struct spi_device *spi) { struct drm_device *drm = spi_get_drvdata(spi); drm_dev_unplug(drm); drm_atomic_helper_shutdown(drm); - - return 0; } static void repaper_shutdown(struct spi_device *spi) |
