diff options
Diffstat (limited to 'drivers/gpu/drm/solomon/ssd130x.c')
| -rw-r--r-- | drivers/gpu/drm/solomon/ssd130x.c | 99 |
1 files changed, 42 insertions, 57 deletions
diff --git a/drivers/gpu/drm/solomon/ssd130x.c b/drivers/gpu/drm/solomon/ssd130x.c index 29b2f82d81f8..96cf39320137 100644 --- a/drivers/gpu/drm/solomon/ssd130x.c +++ b/drivers/gpu/drm/solomon/ssd130x.c @@ -18,9 +18,9 @@ #include <linux/pwm.h> #include <linux/regulator/consumer.h> +#include <drm/clients/drm_client_setup.h> #include <drm/drm_atomic.h> #include <drm/drm_atomic_helper.h> -#include <drm/drm_client_setup.h> #include <drm/drm_crtc_helper.h> #include <drm/drm_damage_helper.h> #include <drm/drm_edid.h> @@ -33,13 +33,13 @@ #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 "ssd130x.h" #define DRIVER_NAME "ssd130x" #define DRIVER_DESC "DRM driver for Solomon SSD13xx OLED displays" -#define DRIVER_DATE "20220131" #define DRIVER_MAJOR 1 #define DRIVER_MINOR 0 @@ -209,7 +209,7 @@ const struct ssd130x_deviceinfo ssd130x_variants[] = { .family_id = SSD133X_FAMILY, } }; -EXPORT_SYMBOL_NS_GPL(ssd130x_variants, DRM_SSD130X); +EXPORT_SYMBOL_NS_GPL(ssd130x_variants, "DRM_SSD130X"); struct ssd130x_crtc_state { struct drm_crtc_state base; @@ -881,7 +881,7 @@ static int ssd132x_update_rect(struct ssd130x_device *ssd130x, u8 n1 = buf[i * width + j]; u8 n2 = buf[i * width + j + 1]; - data_array[array_idx++] = (n2 << 4) | n1; + data_array[array_idx++] = (n2 & 0xf0) | (n1 >> 4); } } @@ -975,7 +975,7 @@ static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array) { - unsigned int columns = DIV_ROUND_UP(ssd130x->height, SSD132X_SEGMENT_WIDTH); + unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH); unsigned int height = ssd130x->height; memset(data_array, 0, columns * height); @@ -1017,15 +1017,9 @@ static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb, dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8); - ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); - if (ret) - return ret; - iosys_map_set_vaddr(&dst, buf); drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state); - drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); - ssd130x_update_rect(ssd130x, rect, buf, data_array); return ret; @@ -1038,7 +1032,7 @@ static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb, struct drm_format_conv_state *fmtcnv_state) { struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev); - unsigned int dst_pitch = drm_rect_width(rect); + unsigned int dst_pitch; struct iosys_map dst; int ret = 0; @@ -1047,15 +1041,11 @@ static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb, rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH), ssd130x->width); - ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); - if (ret) - return ret; + dst_pitch = drm_rect_width(rect); iosys_map_set_vaddr(&dst, buf); drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state); - drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); - ssd132x_update_rect(ssd130x, rect, buf, data_array); return ret; @@ -1077,15 +1067,9 @@ static int ssd133x_fb_blit_rect(struct drm_framebuffer *fb, dst_pitch = drm_format_info_min_pitch(fi, 0, drm_rect_width(rect)); - ret = drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE); - if (ret) - return ret; - iosys_map_set_vaddr(&dst, data_array); drm_fb_xrgb8888_to_rgb332(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state); - drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); - ssd133x_update_rect(ssd130x, rect, data_array, dst_pitch); return ret; @@ -1231,6 +1215,9 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, if (!drm_dev_enter(drm, &idx)) return; + if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE)) + goto out_drm_dev_exit; + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); drm_atomic_for_each_plane_damage(&iter, &damage) { dst_clip = plane_state->dst; @@ -1244,6 +1231,9 @@ static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane, &shadow_plane_state->fmtcnv_state); } + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + +out_drm_dev_exit: drm_dev_exit(idx); } @@ -1266,6 +1256,9 @@ static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane, if (!drm_dev_enter(drm, &idx)) return; + if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE)) + goto out_drm_dev_exit; + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); drm_atomic_for_each_plane_damage(&iter, &damage) { dst_clip = plane_state->dst; @@ -1279,6 +1272,9 @@ static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane, &shadow_plane_state->fmtcnv_state); } + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + +out_drm_dev_exit: drm_dev_exit(idx); } @@ -1300,6 +1296,9 @@ static void ssd133x_primary_plane_atomic_update(struct drm_plane *plane, if (!drm_dev_enter(drm, &idx)) return; + if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE)) + goto out_drm_dev_exit; + drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state); drm_atomic_for_each_plane_damage(&iter, &damage) { dst_clip = plane_state->dst; @@ -1312,6 +1311,9 @@ static void ssd133x_primary_plane_atomic_update(struct drm_plane *plane, &shadow_plane_state->fmtcnv_state); } + drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE); + +out_drm_dev_exit: drm_dev_exit(idx); } @@ -1392,7 +1394,7 @@ static void ssd130x_primary_plane_reset(struct drm_plane *plane) { struct ssd130x_plane_state *ssd130x_state; - WARN_ON(plane->state); + drm_WARN_ON_ONCE(plane->dev, plane->state); ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL); if (!ssd130x_state) @@ -1407,7 +1409,7 @@ static struct drm_plane_state *ssd130x_primary_plane_duplicate_state(struct drm_ struct ssd130x_plane_state *old_ssd130x_state; struct ssd130x_plane_state *ssd130x_state; - if (WARN_ON(!plane->state)) + if (drm_WARN_ON_ONCE(plane->dev, !plane->state)) return NULL; old_ssd130x_state = to_ssd130x_plane_state(plane->state); @@ -1472,15 +1474,7 @@ static enum drm_mode_status ssd130x_crtc_mode_valid(struct drm_crtc *crtc, { struct ssd130x_device *ssd130x = drm_to_ssd130x(crtc->dev); - if (mode->hdisplay != ssd130x->mode.hdisplay && - mode->vdisplay != ssd130x->mode.vdisplay) - return MODE_ONE_SIZE; - else if (mode->hdisplay != ssd130x->mode.hdisplay) - return MODE_ONE_WIDTH; - else if (mode->vdisplay != ssd130x->mode.vdisplay) - return MODE_ONE_HEIGHT; - - return MODE_OK; + return drm_crtc_helper_mode_valid_fixed(crtc, mode, &ssd130x->mode); } static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, @@ -1497,7 +1491,7 @@ static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc, if (ret) return ret; - ssd130x_state->data_array = kmalloc(ssd130x->width * pages, GFP_KERNEL); + ssd130x_state->data_array = kmalloc_array(ssd130x->width, pages, GFP_KERNEL); if (!ssd130x_state->data_array) return -ENOMEM; @@ -1518,7 +1512,7 @@ static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc, if (ret) return ret; - ssd130x_state->data_array = kmalloc(columns * ssd130x->height, GFP_KERNEL); + ssd130x_state->data_array = kmalloc_array(columns, ssd130x->height, GFP_KERNEL); if (!ssd130x_state->data_array) return -ENOMEM; @@ -1545,7 +1539,7 @@ static int ssd133x_crtc_atomic_check(struct drm_crtc *crtc, pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width); - ssd130x_state->data_array = kmalloc(pitch * ssd130x->height, GFP_KERNEL); + ssd130x_state->data_array = kmalloc_array(pitch, ssd130x->height, GFP_KERNEL); if (!ssd130x_state->data_array) return -ENOMEM; @@ -1557,7 +1551,7 @@ static void ssd130x_crtc_reset(struct drm_crtc *crtc) { struct ssd130x_crtc_state *ssd130x_state; - WARN_ON(crtc->state); + drm_WARN_ON_ONCE(crtc->dev, crtc->state); ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL); if (!ssd130x_state) @@ -1571,7 +1565,7 @@ static struct drm_crtc_state *ssd130x_crtc_duplicate_state(struct drm_crtc *crtc struct ssd130x_crtc_state *old_ssd130x_state; struct ssd130x_crtc_state *ssd130x_state; - if (WARN_ON(!crtc->state)) + if (drm_WARN_ON_ONCE(crtc->dev, !crtc->state)) return NULL; old_ssd130x_state = to_ssd130x_crtc_state(crtc->state); @@ -1739,20 +1733,8 @@ static const struct drm_encoder_funcs ssd130x_encoder_funcs = { static int ssd130x_connector_get_modes(struct drm_connector *connector) { struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev); - struct drm_display_mode *mode; - struct device *dev = ssd130x->dev; - - mode = drm_mode_duplicate(connector->dev, &ssd130x->mode); - if (!mode) { - dev_err(dev, "Failed to duplicated mode\n"); - return 0; - } - - drm_mode_probed_add(connector, mode); - drm_set_preferred_mode(connector, mode->hdisplay, mode->vdisplay); - /* There is only a single mode */ - return 1; + return drm_connector_helper_get_modes_fixed(connector, &ssd130x->mode); } static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = { @@ -1784,7 +1766,6 @@ static const struct drm_driver ssd130x_drm_driver = { DRM_FBDEV_SHMEM_DRIVER_OPS, .name = DRIVER_NAME, .desc = DRIVER_DESC, - .date = DRIVER_DATE, .major = DRIVER_MAJOR, .minor = DRIVER_MINOR, .driver_features = DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET, @@ -1887,10 +1868,14 @@ static int ssd130x_init_modeset(struct ssd130x_device *ssd130x) mode->type = DRM_MODE_TYPE_DRIVER; mode->clock = 1; - mode->hdisplay = mode->htotal = ssd130x->width; - mode->hsync_start = mode->hsync_end = ssd130x->width; - mode->vdisplay = mode->vtotal = ssd130x->height; - mode->vsync_start = mode->vsync_end = ssd130x->height; + mode->hdisplay = ssd130x->width; + mode->htotal = ssd130x->width; + mode->hsync_start = ssd130x->width; + mode->hsync_end = ssd130x->width; + mode->vdisplay = ssd130x->height; + mode->vtotal = ssd130x->height; + mode->vsync_start = ssd130x->height; + mode->vsync_end = ssd130x->height; mode->width_mm = 27; mode->height_mm = 27; |
