summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/tiny/repaper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/tiny/repaper.c')
-rw-r--r--drivers/gpu/drm/tiny/repaper.c110
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)