File Index
Files and directories
Sign in
FILE

ssd130x.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/solomon/ssd130x.c C
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * DRM driver for Solomon SSD13xx OLED displays
   4 *
   5 * Copyright 2022 Red Hat Inc.
   6 * Author: Javier Martinez Canillas <javierm@redhat.com>
   7 *
   8 * Based on drivers/video/fbdev/ssd1307fb.c
   9 * Copyright 2012 Free Electrons
  10 */
  11
  12#include <linux/backlight.h>
  13#include <linux/bitfield.h>
  14#include <linux/bits.h>
  15#include <linux/delay.h>
  16#include <linux/gpio/consumer.h>
  17#include <linux/property.h>
  18#include <linux/pwm.h>
  19#include <linux/regulator/consumer.h>
  20
  21#include <drm/clients/drm_client_setup.h>
  22#include <drm/drm_atomic.h>
  23#include <drm/drm_atomic_helper.h>
  24#include <drm/drm_crtc_helper.h>
  25#include <drm/drm_damage_helper.h>
  26#include <drm/drm_edid.h>
  27#include <drm/drm_fbdev_shmem.h>
  28#include <drm/drm_format_helper.h>
  29#include <drm/drm_framebuffer.h>
  30#include <drm/drm_gem_atomic_helper.h>
  31#include <drm/drm_gem_framebuffer_helper.h>
  32#include <drm/drm_gem_shmem_helper.h>
  33#include <drm/drm_managed.h>
  34#include <drm/drm_modes.h>
  35#include <drm/drm_rect.h>
  36#include <drm/drm_print.h>
  37#include <drm/drm_probe_helper.h>
  38
  39#include "ssd130x.h"
  40
  41#define DRIVER_NAME	"ssd130x"
  42#define DRIVER_DESC	"DRM driver for Solomon SSD13xx OLED displays"
  43#define DRIVER_MAJOR	1
  44#define DRIVER_MINOR	0
  45
  46#define SSD130X_PAGE_HEIGHT 8
  47
  48#define SSD132X_SEGMENT_WIDTH 2
  49
  50/* ssd13xx commands */
  51#define SSD13XX_CONTRAST			0x81
  52#define SSD13XX_SET_SEG_REMAP			0xa0
  53#define SSD13XX_SET_MULTIPLEX_RATIO		0xa8
  54#define SSD13XX_DISPLAY_OFF			0xae
  55#define SSD13XX_DISPLAY_ON			0xaf
  56
  57#define SSD13XX_SET_SEG_REMAP_MASK		GENMASK(0, 0)
  58#define SSD13XX_SET_SEG_REMAP_SET(val)		FIELD_PREP(SSD13XX_SET_SEG_REMAP_MASK, (val))
  59
  60/* ssd130x commands */
  61#define SSD130X_PAGE_COL_START_LOW		0x00
  62#define SSD130X_PAGE_COL_START_HIGH		0x10
  63#define SSD130X_SET_ADDRESS_MODE		0x20
  64#define SSD130X_SET_COL_RANGE			0x21
  65#define SSD130X_SET_PAGE_RANGE			0x22
  66#define SSD130X_SET_LOOKUP_TABLE		0x91
  67#define SSD130X_CHARGE_PUMP			0x8d
  68#define SSD130X_START_PAGE_ADDRESS		0xb0
  69#define SSD130X_SET_COM_SCAN_DIR		0xc0
  70#define SSD130X_SET_DISPLAY_OFFSET		0xd3
  71#define SSD130X_SET_CLOCK_FREQ			0xd5
  72#define SSD130X_SET_AREA_COLOR_MODE		0xd8
  73#define SSD130X_SET_PRECHARGE_PERIOD		0xd9
  74#define SSD130X_SET_COM_PINS_CONFIG		0xda
  75#define SSD130X_SET_VCOMH			0xdb
  76
  77/* ssd130x commands accessors */
  78#define SSD130X_PAGE_COL_START_MASK		GENMASK(3, 0)
  79#define SSD130X_PAGE_COL_START_HIGH_SET(val)	FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val) >> 4)
  80#define SSD130X_PAGE_COL_START_LOW_SET(val)	FIELD_PREP(SSD130X_PAGE_COL_START_MASK, (val))
  81#define SSD130X_START_PAGE_ADDRESS_MASK		GENMASK(2, 0)
  82#define SSD130X_START_PAGE_ADDRESS_SET(val)	FIELD_PREP(SSD130X_START_PAGE_ADDRESS_MASK, (val))
  83#define SSD130X_SET_COM_SCAN_DIR_MASK		GENMASK(3, 3)
  84#define SSD130X_SET_COM_SCAN_DIR_SET(val)	FIELD_PREP(SSD130X_SET_COM_SCAN_DIR_MASK, (val))
  85#define SSD130X_SET_CLOCK_DIV_MASK		GENMASK(3, 0)
  86#define SSD130X_SET_CLOCK_DIV_SET(val)		FIELD_PREP(SSD130X_SET_CLOCK_DIV_MASK, (val))
  87#define SSD130X_SET_CLOCK_FREQ_MASK		GENMASK(7, 4)
  88#define SSD130X_SET_CLOCK_FREQ_SET(val)		FIELD_PREP(SSD130X_SET_CLOCK_FREQ_MASK, (val))
  89#define SSD130X_SET_PRECHARGE_PERIOD1_MASK	GENMASK(3, 0)
  90#define SSD130X_SET_PRECHARGE_PERIOD1_SET(val)	FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD1_MASK, (val))
  91#define SSD130X_SET_PRECHARGE_PERIOD2_MASK	GENMASK(7, 4)
  92#define SSD130X_SET_PRECHARGE_PERIOD2_SET(val)	FIELD_PREP(SSD130X_SET_PRECHARGE_PERIOD2_MASK, (val))
  93#define SSD130X_SET_COM_PINS_CONFIG1_MASK	GENMASK(4, 4)
  94#define SSD130X_SET_COM_PINS_CONFIG1_SET(val)	FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG1_MASK, (val))
  95#define SSD130X_SET_COM_PINS_CONFIG2_MASK	GENMASK(5, 5)
  96#define SSD130X_SET_COM_PINS_CONFIG2_SET(val)	FIELD_PREP(SSD130X_SET_COM_PINS_CONFIG2_MASK, (val))
  97
  98#define SSD130X_SET_ADDRESS_MODE_HORIZONTAL	0x00
  99#define SSD130X_SET_ADDRESS_MODE_VERTICAL	0x01
 100#define SSD130X_SET_ADDRESS_MODE_PAGE		0x02
 101
 102#define SSD130X_SET_AREA_COLOR_MODE_ENABLE	0x1e
 103#define SSD130X_SET_AREA_COLOR_MODE_LOW_POWER	0x05
 104
 105/* ssd132x commands */
 106#define SSD132X_SET_COL_RANGE			0x15
 107#define SSD132X_SET_DEACTIVATE_SCROLL		0x2e
 108#define SSD132X_SET_ROW_RANGE			0x75
 109#define SSD132X_SET_DISPLAY_START		0xa1
 110#define SSD132X_SET_DISPLAY_OFFSET		0xa2
 111#define SSD132X_SET_DISPLAY_NORMAL		0xa4
 112#define SSD132X_SET_FUNCTION_SELECT_A		0xab
 113#define SSD132X_SET_PHASE_LENGTH		0xb1
 114#define SSD132X_SET_CLOCK_FREQ			0xb3
 115#define SSD132X_SET_GPIO			0xb5
 116#define SSD132X_SET_PRECHARGE_PERIOD		0xb6
 117#define SSD132X_SET_GRAY_SCALE_TABLE		0xb8
 118#define SSD132X_SELECT_DEFAULT_TABLE		0xb9
 119#define SSD132X_SET_PRECHARGE_VOLTAGE		0xbc
 120#define SSD130X_SET_VCOMH_VOLTAGE		0xbe
 121#define SSD132X_SET_FUNCTION_SELECT_B		0xd5
 122
 123/* ssd133x commands */
 124#define SSD133X_SET_COL_RANGE			0x15
 125#define SSD133X_SET_ROW_RANGE			0x75
 126#define SSD133X_CONTRAST_A			0x81
 127#define SSD133X_CONTRAST_B			0x82
 128#define SSD133X_CONTRAST_C			0x83
 129#define SSD133X_SET_MASTER_CURRENT		0x87
 130#define SSD132X_SET_PRECHARGE_A			0x8a
 131#define SSD132X_SET_PRECHARGE_B			0x8b
 132#define SSD132X_SET_PRECHARGE_C			0x8c
 133#define SSD133X_SET_DISPLAY_START		0xa1
 134#define SSD133X_SET_DISPLAY_OFFSET		0xa2
 135#define SSD133X_SET_DISPLAY_NORMAL		0xa4
 136#define SSD133X_SET_MASTER_CONFIG		0xad
 137#define SSD133X_POWER_SAVE_MODE			0xb0
 138#define SSD133X_PHASES_PERIOD			0xb1
 139#define SSD133X_SET_CLOCK_FREQ			0xb3
 140#define SSD133X_SET_PRECHARGE_VOLTAGE		0xbb
 141#define SSD133X_SET_VCOMH_VOLTAGE		0xbe
 142
 143#define MAX_CONTRAST 255
 144
 145const struct ssd130x_deviceinfo ssd130x_variants[] = {
 146	[SH1106_ID] = {
 147		.default_vcomh = 0x40,
 148		.default_dclk_div = 1,
 149		.default_dclk_frq = 5,
 150		.default_width = 132,
 151		.default_height = 64,
 152		.page_mode_only = 1,
 153		.family_id = SSD130X_FAMILY,
 154	},
 155	[SSD1305_ID] = {
 156		.default_vcomh = 0x34,
 157		.default_dclk_div = 1,
 158		.default_dclk_frq = 7,
 159		.default_width = 132,
 160		.default_height = 64,
 161		.family_id = SSD130X_FAMILY,
 162	},
 163	[SSD1306_ID] = {
 164		.default_vcomh = 0x20,
 165		.default_dclk_div = 1,
 166		.default_dclk_frq = 8,
 167		.need_chargepump = 1,
 168		.default_width = 128,
 169		.default_height = 64,
 170		.family_id = SSD130X_FAMILY,
 171	},
 172	[SSD1307_ID] = {
 173		.default_vcomh = 0x20,
 174		.default_dclk_div = 2,
 175		.default_dclk_frq = 12,
 176		.need_pwm = 1,
 177		.default_width = 128,
 178		.default_height = 39,
 179		.family_id = SSD130X_FAMILY,
 180	},
 181	[SSD1309_ID] = {
 182		.default_vcomh = 0x34,
 183		.default_dclk_div = 1,
 184		.default_dclk_frq = 10,
 185		.default_width = 128,
 186		.default_height = 64,
 187		.family_id = SSD130X_FAMILY,
 188	},
 189	/* ssd132x family */
 190	[SSD1322_ID] = {
 191		.default_width = 480,
 192		.default_height = 128,
 193		.family_id = SSD132X_FAMILY,
 194	},
 195	[SSD1325_ID] = {
 196		.default_width = 128,
 197		.default_height = 80,
 198		.family_id = SSD132X_FAMILY,
 199	},
 200	[SSD1327_ID] = {
 201		.default_width = 128,
 202		.default_height = 128,
 203		.family_id = SSD132X_FAMILY,
 204	},
 205	/* ssd133x family */
 206	[SSD1331_ID] = {
 207		.default_width = 96,
 208		.default_height = 64,
 209		.family_id = SSD133X_FAMILY,
 210	}
 211};
 212EXPORT_SYMBOL_NS_GPL(ssd130x_variants, "DRM_SSD130X");
 213
 214struct ssd130x_crtc_state {
 215	struct drm_crtc_state base;
 216	/* Buffer to store pixels in HW format and written to the panel */
 217	u8 *data_array;
 218};
 219
 220struct ssd130x_plane_state {
 221	struct drm_shadow_plane_state base;
 222	/* Intermediate buffer to convert pixels from XRGB8888 to HW format */
 223	u8 *buffer;
 224};
 225
 226static inline struct ssd130x_crtc_state *to_ssd130x_crtc_state(struct drm_crtc_state *state)
 227{
 228	return container_of(state, struct ssd130x_crtc_state, base);
 229}
 230
 231static inline struct ssd130x_plane_state *to_ssd130x_plane_state(struct drm_plane_state *state)
 232{
 233	return container_of(state, struct ssd130x_plane_state, base.base);
 234}
 235
 236static inline struct ssd130x_device *drm_to_ssd130x(struct drm_device *drm)
 237{
 238	return container_of(drm, struct ssd130x_device, drm);
 239}
 240
 241/*
 242 * Helper to write data (SSD13XX_DATA) to the device.
 243 */
 244static int ssd130x_write_data(struct ssd130x_device *ssd130x, u8 *values, int count)
 245{
 246	return regmap_bulk_write(ssd130x->regmap, SSD13XX_DATA, values, count);
 247}
 248
 249/*
 250 * Helper to write command (SSD13XX_COMMAND). The fist variadic argument
 251 * is the command to write and the following are the command options.
 252 *
 253 * Note that the ssd13xx protocol requires each command and option to be
 254 * written as a SSD13XX_COMMAND device register value. That is why a call
 255 * to regmap_write(..., SSD13XX_COMMAND, ...) is done for each argument.
 256 */
 257static int ssd130x_write_cmd(struct ssd130x_device *ssd130x, int count,
 258			     /* u8 cmd, u8 option, ... */...)
 259{
 260	va_list ap;
 261	u8 value;
 262	int ret;
 263
 264	va_start(ap, count);
 265
 266	do {
 267		value = va_arg(ap, int);
 268		ret = regmap_write(ssd130x->regmap, SSD13XX_COMMAND, value);
 269		if (ret)
 270			goto out_end;
 271	} while (--count);
 272
 273out_end:
 274	va_end(ap);
 275
 276	return ret;
 277}
 278
 279/* Set address range for horizontal/vertical addressing modes */
 280static int ssd130x_set_col_range(struct ssd130x_device *ssd130x,
 281				 u8 col_start, u8 cols)
 282{
 283	u8 col_end = col_start + cols - 1;
 284	int ret;
 285
 286	if (col_start == ssd130x->col_start && col_end == ssd130x->col_end)
 287		return 0;
 288
 289	ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_COL_RANGE, col_start, col_end);
 290	if (ret < 0)
 291		return ret;
 292
 293	ssd130x->col_start = col_start;
 294	ssd130x->col_end = col_end;
 295	return 0;
 296}
 297
 298static int ssd130x_set_page_range(struct ssd130x_device *ssd130x,
 299				  u8 page_start, u8 pages)
 300{
 301	u8 page_end = page_start + pages - 1;
 302	int ret;
 303
 304	if (page_start == ssd130x->page_start && page_end == ssd130x->page_end)
 305		return 0;
 306
 307	ret = ssd130x_write_cmd(ssd130x, 3, SSD130X_SET_PAGE_RANGE, page_start, page_end);
 308	if (ret < 0)
 309		return ret;
 310
 311	ssd130x->page_start = page_start;
 312	ssd130x->page_end = page_end;
 313	return 0;
 314}
 315
 316/* Set page and column start address for page addressing mode */
 317static int ssd130x_set_page_pos(struct ssd130x_device *ssd130x,
 318				u8 page_start, u8 col_start)
 319{
 320	int ret;
 321	u32 page, col_low, col_high;
 322
 323	page = SSD130X_START_PAGE_ADDRESS |
 324	       SSD130X_START_PAGE_ADDRESS_SET(page_start);
 325	col_low = SSD130X_PAGE_COL_START_LOW |
 326		  SSD130X_PAGE_COL_START_LOW_SET(col_start);
 327	col_high = SSD130X_PAGE_COL_START_HIGH |
 328		   SSD130X_PAGE_COL_START_HIGH_SET(col_start);
 329	ret = ssd130x_write_cmd(ssd130x, 3, page, col_low, col_high);
 330	if (ret < 0)
 331		return ret;
 332
 333	return 0;
 334}
 335
 336static int ssd130x_pwm_enable(struct ssd130x_device *ssd130x)
 337{
 338	struct device *dev = ssd130x->dev;
 339	struct pwm_state pwmstate;
 340
 341	ssd130x->pwm = pwm_get(dev, NULL);
 342	if (IS_ERR(ssd130x->pwm)) {
 343		dev_err(dev, "Could not get PWM from firmware description!\n");
 344		return PTR_ERR(ssd130x->pwm);
 345	}
 346
 347	pwm_init_state(ssd130x->pwm, &pwmstate);
 348	pwm_set_relative_duty_cycle(&pwmstate, 50, 100);
 349	pwm_apply_might_sleep(ssd130x->pwm, &pwmstate);
 350
 351	/* Enable the PWM */
 352	pwm_enable(ssd130x->pwm);
 353
 354	dev_dbg(dev, "Using PWM %s with a %lluns period.\n",
 355		ssd130x->pwm->label, pwm_get_period(ssd130x->pwm));
 356
 357	return 0;
 358}
 359
 360static void ssd130x_reset(struct ssd130x_device *ssd130x)
 361{
 362	if (!ssd130x->reset)
 363		return;
 364
 365	/* Reset the screen */
 366	gpiod_set_value_cansleep(ssd130x->reset, 1);
 367	udelay(4);
 368	gpiod_set_value_cansleep(ssd130x->reset, 0);
 369	udelay(4);
 370}
 371
 372static int ssd130x_power_on(struct ssd130x_device *ssd130x)
 373{
 374	struct device *dev = ssd130x->dev;
 375	int ret;
 376
 377	ssd130x_reset(ssd130x);
 378
 379	ret = regulator_enable(ssd130x->vcc_reg);
 380	if (ret) {
 381		dev_err(dev, "Failed to enable VCC: %d\n", ret);
 382		return ret;
 383	}
 384
 385	if (ssd130x->device_info->need_pwm) {
 386		ret = ssd130x_pwm_enable(ssd130x);
 387		if (ret) {
 388			dev_err(dev, "Failed to enable PWM: %d\n", ret);
 389			regulator_disable(ssd130x->vcc_reg);
 390			return ret;
 391		}
 392	}
 393
 394	return 0;
 395}
 396
 397static void ssd130x_power_off(struct ssd130x_device *ssd130x)
 398{
 399	pwm_disable(ssd130x->pwm);
 400	pwm_put(ssd130x->pwm);
 401
 402	regulator_disable(ssd130x->vcc_reg);
 403}
 404
 405static int ssd130x_init(struct ssd130x_device *ssd130x)
 406{
 407	u32 precharge, dclk, com_invdir, compins, chargepump, seg_remap;
 408	bool scan_mode;
 409	int ret;
 410
 411	/* Set initial contrast */
 412	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, ssd130x->contrast);
 413	if (ret < 0)
 414		return ret;
 415
 416	/* Set segment re-map */
 417	seg_remap = (SSD13XX_SET_SEG_REMAP |
 418		     SSD13XX_SET_SEG_REMAP_SET(ssd130x->seg_remap));
 419	ret = ssd130x_write_cmd(ssd130x, 1, seg_remap);
 420	if (ret < 0)
 421		return ret;
 422
 423	/* Set COM direction */
 424	com_invdir = (SSD130X_SET_COM_SCAN_DIR |
 425		      SSD130X_SET_COM_SCAN_DIR_SET(ssd130x->com_invdir));
 426	ret = ssd130x_write_cmd(ssd130x,  1, com_invdir);
 427	if (ret < 0)
 428		return ret;
 429
 430	/* Set multiplex ratio value */
 431	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
 432	if (ret < 0)
 433		return ret;
 434
 435	/* set display offset value */
 436	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_DISPLAY_OFFSET, ssd130x->com_offset);
 437	if (ret < 0)
 438		return ret;
 439
 440	/* Set clock frequency */
 441	dclk = (SSD130X_SET_CLOCK_DIV_SET(ssd130x->dclk_div - 1) |
 442		SSD130X_SET_CLOCK_FREQ_SET(ssd130x->dclk_frq));
 443	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_CLOCK_FREQ, dclk);
 444	if (ret < 0)
 445		return ret;
 446
 447	/* Set Area Color Mode ON/OFF & Low Power Display Mode */
 448	if (ssd130x->area_color_enable || ssd130x->low_power) {
 449		u32 mode = 0;
 450
 451		if (ssd130x->area_color_enable)
 452			mode |= SSD130X_SET_AREA_COLOR_MODE_ENABLE;
 453
 454		if (ssd130x->low_power)
 455			mode |= SSD130X_SET_AREA_COLOR_MODE_LOW_POWER;
 456
 457		ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_AREA_COLOR_MODE, mode);
 458		if (ret < 0)
 459			return ret;
 460	}
 461
 462	/* Set precharge period in number of ticks from the internal clock */
 463	precharge = (SSD130X_SET_PRECHARGE_PERIOD1_SET(ssd130x->prechargep1) |
 464		     SSD130X_SET_PRECHARGE_PERIOD2_SET(ssd130x->prechargep2));
 465	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_PRECHARGE_PERIOD, precharge);
 466	if (ret < 0)
 467		return ret;
 468
 469	/* Set COM pins configuration */
 470	compins = BIT(1);
 471	/*
 472	 * The COM scan mode field values are the inverse of the boolean DT
 473	 * property "solomon,com-seq". The value 0b means scan from COM0 to
 474	 * COM[N - 1] while 1b means scan from COM[N - 1] to COM0.
 475	 */
 476	scan_mode = !ssd130x->com_seq;
 477	compins |= (SSD130X_SET_COM_PINS_CONFIG1_SET(scan_mode) |
 478		    SSD130X_SET_COM_PINS_CONFIG2_SET(ssd130x->com_lrremap));
 479	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_COM_PINS_CONFIG, compins);
 480	if (ret < 0)
 481		return ret;
 482
 483	/* Set VCOMH */
 484	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH, ssd130x->vcomh);
 485	if (ret < 0)
 486		return ret;
 487
 488	/* Turn on the DC-DC Charge Pump */
 489	chargepump = BIT(4);
 490
 491	if (ssd130x->device_info->need_chargepump)
 492		chargepump |= BIT(2);
 493
 494	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_CHARGE_PUMP, chargepump);
 495	if (ret < 0)
 496		return ret;
 497
 498	/* Set lookup table */
 499	if (ssd130x->lookup_table_set) {
 500		int i;
 501
 502		ret = ssd130x_write_cmd(ssd130x, 1, SSD130X_SET_LOOKUP_TABLE);
 503		if (ret < 0)
 504			return ret;
 505
 506		for (i = 0; i < ARRAY_SIZE(ssd130x->lookup_table); i++) {
 507			u8 val = ssd130x->lookup_table[i];
 508
 509			if (val < 31 || val > 63)
 510				dev_warn(ssd130x->dev,
 511					 "lookup table index %d value out of range 31 <= %d <= 63\n",
 512					 i, val);
 513			ret = ssd130x_write_cmd(ssd130x, 1, val);
 514			if (ret < 0)
 515				return ret;
 516		}
 517	}
 518
 519	/* Switch to page addressing mode */
 520	if (ssd130x->page_address_mode)
 521		return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
 522					 SSD130X_SET_ADDRESS_MODE_PAGE);
 523
 524	/* Switch to horizontal addressing mode */
 525	return ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_ADDRESS_MODE,
 526				 SSD130X_SET_ADDRESS_MODE_HORIZONTAL);
 527}
 528
 529static int ssd132x_init(struct ssd130x_device *ssd130x)
 530{
 531	int ret;
 532
 533	/* Set initial contrast */
 534	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_CONTRAST, 0x80);
 535	if (ret < 0)
 536		return ret;
 537
 538	/* Set column start and end */
 539	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, 0x00,
 540				ssd130x->width / SSD132X_SEGMENT_WIDTH - 1);
 541	if (ret < 0)
 542		return ret;
 543
 544	/* Set row start and end */
 545	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, 0x00, ssd130x->height - 1);
 546	if (ret < 0)
 547		return ret;
 548	/*
 549	 * Horizontal Address Increment
 550	 * Re-map for Column Address, Nibble and COM
 551	 * COM Split Odd Even
 552	 */
 553	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x53);
 554	if (ret < 0)
 555		return ret;
 556
 557	/* Set display start and offset */
 558	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_START, 0x00);
 559	if (ret < 0)
 560		return ret;
 561
 562	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_DISPLAY_OFFSET, 0x00);
 563	if (ret < 0)
 564		return ret;
 565
 566	/* Set display mode normal */
 567	ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SET_DISPLAY_NORMAL);
 568	if (ret < 0)
 569		return ret;
 570
 571	/* Set multiplex ratio value */
 572	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
 573	if (ret < 0)
 574		return ret;
 575
 576	/* Set phase length */
 577	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PHASE_LENGTH, 0x55);
 578	if (ret < 0)
 579		return ret;
 580
 581	/* Select default linear gray scale table */
 582	ret = ssd130x_write_cmd(ssd130x, 1, SSD132X_SELECT_DEFAULT_TABLE);
 583	if (ret < 0)
 584		return ret;
 585
 586	/* Set clock frequency */
 587	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_CLOCK_FREQ, 0x01);
 588	if (ret < 0)
 589		return ret;
 590
 591	/* Enable internal VDD regulator */
 592	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_A, 0x1);
 593	if (ret < 0)
 594		return ret;
 595
 596	/* Set pre-charge period */
 597	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_PERIOD, 0x01);
 598	if (ret < 0)
 599		return ret;
 600
 601	/* Set pre-charge voltage */
 602	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_VOLTAGE, 0x08);
 603	if (ret < 0)
 604		return ret;
 605
 606	/* Set VCOMH voltage */
 607	ret = ssd130x_write_cmd(ssd130x, 2, SSD130X_SET_VCOMH_VOLTAGE, 0x07);
 608	if (ret < 0)
 609		return ret;
 610
 611	/* Enable second pre-charge and internal VSL */
 612	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_FUNCTION_SELECT_B, 0x62);
 613	if (ret < 0)
 614		return ret;
 615
 616	return 0;
 617}
 618
 619static int ssd133x_init(struct ssd130x_device *ssd130x)
 620{
 621	int ret;
 622
 623	/* Set color A contrast */
 624	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_A, 0x91);
 625	if (ret < 0)
 626		return ret;
 627
 628	/* Set color B contrast */
 629	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_B, 0x50);
 630	if (ret < 0)
 631		return ret;
 632
 633	/* Set color C contrast */
 634	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_CONTRAST_C, 0x7d);
 635	if (ret < 0)
 636		return ret;
 637
 638	/* Set master current */
 639	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_MASTER_CURRENT, 0x06);
 640	if (ret < 0)
 641		return ret;
 642
 643	/* Set column start and end */
 644	ret = ssd130x_write_cmd(ssd130x, 3, SSD133X_SET_COL_RANGE, 0x00, ssd130x->width - 1);
 645	if (ret < 0)
 646		return ret;
 647
 648	/* Set row start and end */
 649	ret = ssd130x_write_cmd(ssd130x, 3, SSD133X_SET_ROW_RANGE, 0x00, ssd130x->height - 1);
 650	if (ret < 0)
 651		return ret;
 652
 653	/*
 654	 * Horizontal Address Increment
 655	 * Normal order SA,SB,SC (e.g. RGB)
 656	 * COM Split Odd Even
 657	 * 256 color format
 658	 */
 659	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_SEG_REMAP, 0x20);
 660	if (ret < 0)
 661		return ret;
 662
 663	/* Set display start and offset */
 664	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_DISPLAY_START, 0x00);
 665	if (ret < 0)
 666		return ret;
 667
 668	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_DISPLAY_OFFSET, 0x00);
 669	if (ret < 0)
 670		return ret;
 671
 672	/* Set display mode normal */
 673	ret = ssd130x_write_cmd(ssd130x, 1, SSD133X_SET_DISPLAY_NORMAL);
 674	if (ret < 0)
 675		return ret;
 676
 677	/* Set multiplex ratio value */
 678	ret = ssd130x_write_cmd(ssd130x, 2, SSD13XX_SET_MULTIPLEX_RATIO, ssd130x->height - 1);
 679	if (ret < 0)
 680		return ret;
 681
 682	/* Set master configuration */
 683	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_MASTER_CONFIG, 0x8e);
 684	if (ret < 0)
 685		return ret;
 686
 687	/* Set power mode */
 688	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_POWER_SAVE_MODE, 0x0b);
 689	if (ret < 0)
 690		return ret;
 691
 692	/* Set Phase 1 and 2 period */
 693	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_PHASES_PERIOD, 0x31);
 694	if (ret < 0)
 695		return ret;
 696
 697	/* Set clock divider */
 698	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_CLOCK_FREQ, 0xf0);
 699	if (ret < 0)
 700		return ret;
 701
 702	/* Set pre-charge A */
 703	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_A, 0x64);
 704	if (ret < 0)
 705		return ret;
 706
 707	/* Set pre-charge B */
 708	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_B, 0x78);
 709	if (ret < 0)
 710		return ret;
 711
 712	/* Set pre-charge C */
 713	ret = ssd130x_write_cmd(ssd130x, 2, SSD132X_SET_PRECHARGE_C, 0x64);
 714	if (ret < 0)
 715		return ret;
 716
 717	/* Set pre-charge level */
 718	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_PRECHARGE_VOLTAGE, 0x3a);
 719	if (ret < 0)
 720		return ret;
 721
 722	/* Set VCOMH voltage */
 723	ret = ssd130x_write_cmd(ssd130x, 2, SSD133X_SET_VCOMH_VOLTAGE, 0x3e);
 724	if (ret < 0)
 725		return ret;
 726
 727	return 0;
 728}
 729
 730static int ssd130x_update_rect(struct ssd130x_device *ssd130x,
 731			       struct drm_rect *rect, u8 *buf,
 732			       u8 *data_array)
 733{
 734	unsigned int x = rect->x1;
 735	unsigned int y = rect->y1;
 736	unsigned int width = drm_rect_width(rect);
 737	unsigned int height = drm_rect_height(rect);
 738	unsigned int line_length = DIV_ROUND_UP(width, 8);
 739	unsigned int page_height = SSD130X_PAGE_HEIGHT;
 740	u8 page_start = ssd130x->page_offset + y / page_height;
 741	unsigned int pages = DIV_ROUND_UP(height, page_height);
 742	struct drm_device *drm = &ssd130x->drm;
 743	u32 array_idx = 0;
 744	int ret, i, j, k;
 745
 746	drm_WARN_ONCE(drm, y % page_height != 0, "y must be aligned to screen page\n");
 747
 748	/*
 749	 * The screen is divided in pages, each having a height of 8
 750	 * pixels, and the width of the screen. When sending a byte of
 751	 * data to the controller, it gives the 8 bits for the current
 752	 * column. I.e, the first byte are the 8 bits of the first
 753	 * column, then the 8 bits for the second column, etc.
 754	 *
 755	 *
 756	 * Representation of the screen, assuming it is 5 bits
 757	 * wide. Each letter-number combination is a bit that controls
 758	 * one pixel.
 759	 *
 760	 * A0 A1 A2 A3 A4
 761	 * B0 B1 B2 B3 B4
 762	 * C0 C1 C2 C3 C4
 763	 * D0 D1 D2 D3 D4
 764	 * E0 E1 E2 E3 E4
 765	 * F0 F1 F2 F3 F4
 766	 * G0 G1 G2 G3 G4
 767	 * H0 H1 H2 H3 H4
 768	 *
 769	 * If you want to update this screen, you need to send 5 bytes:
 770	 *  (1) A0 B0 C0 D0 E0 F0 G0 H0
 771	 *  (2) A1 B1 C1 D1 E1 F1 G1 H1
 772	 *  (3) A2 B2 C2 D2 E2 F2 G2 H2
 773	 *  (4) A3 B3 C3 D3 E3 F3 G3 H3
 774	 *  (5) A4 B4 C4 D4 E4 F4 G4 H4
 775	 */
 776
 777	if (!ssd130x->page_address_mode) {
 778		/* Set address range for horizontal addressing mode */
 779		ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset + x, width);
 780		if (ret < 0)
 781			return ret;
 782
 783		ret = ssd130x_set_page_range(ssd130x, page_start, pages);
 784		if (ret < 0)
 785			return ret;
 786	}
 787
 788	for (i = 0; i < pages; i++) {
 789		int m = page_height;
 790
 791		/* Last page may be partial */
 792		if (page_height * (y / page_height + i + 1) > ssd130x->height)
 793			m = ssd130x->height % page_height;
 794
 795		for (j = 0; j < width; j++) {
 796			u8 data = 0;
 797
 798			for (k = 0; k < m; k++) {
 799				u32 idx = (page_height * i + k) * line_length + j / 8;
 800				u8 byte = buf[idx];
 801				u8 bit = (byte >> (j % 8)) & 1;
 802
 803				data |= bit << k;
 804			}
 805			data_array[array_idx++] = data;
 806		}
 807
 808		/*
 809		 * In page addressing mode, the start address needs to be reset,
 810		 * and each page then needs to be written out separately.
 811		 */
 812		if (ssd130x->page_address_mode) {
 813			ret = ssd130x_set_page_pos(ssd130x,
 814						   page_start + i,
 815						   ssd130x->col_offset + x);
 816			if (ret < 0)
 817				return ret;
 818
 819			ret = ssd130x_write_data(ssd130x, data_array, width);
 820			if (ret < 0)
 821				return ret;
 822
 823			array_idx = 0;
 824		}
 825	}
 826
 827	/* Write out update in one go if we aren't using page addressing mode */
 828	if (!ssd130x->page_address_mode)
 829		ret = ssd130x_write_data(ssd130x, data_array, width * pages);
 830
 831	return ret;
 832}
 833
 834static int ssd132x_update_rect(struct ssd130x_device *ssd130x,
 835			       struct drm_rect *rect, u8 *buf,
 836			       u8 *data_array)
 837{
 838	unsigned int x = rect->x1;
 839	unsigned int y = rect->y1;
 840	unsigned int segment_width = SSD132X_SEGMENT_WIDTH;
 841	unsigned int width = drm_rect_width(rect);
 842	unsigned int height = drm_rect_height(rect);
 843	unsigned int columns = DIV_ROUND_UP(width, segment_width);
 844	unsigned int rows = height;
 845	struct drm_device *drm = &ssd130x->drm;
 846	u32 array_idx = 0;
 847	unsigned int i, j;
 848	int ret;
 849
 850	drm_WARN_ONCE(drm, x % segment_width != 0, "x must be aligned to screen segment\n");
 851
 852	/*
 853	 * The screen is divided in Segment and Common outputs, where
 854	 * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
 855	 * the columns.
 856	 *
 857	 * Each Segment has a 4-bit pixel and each Common output has a
 858	 * row of pixels. When using the (default) horizontal address
 859	 * increment mode, each byte of data sent to the controller has
 860	 * two Segments (e.g: SEG0 and SEG1) that are stored in the lower
 861	 * and higher nibbles of a single byte representing one column.
 862	 * That is, the first byte are SEG0 (D0[3:0]) and SEG1 (D0[7:4]),
 863	 * the second byte are SEG2 (D1[3:0]) and SEG3 (D1[7:4]) and so on.
 864	 */
 865
 866	/* Set column start and end */
 867	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_COL_RANGE, x / segment_width, columns - 1);
 868	if (ret < 0)
 869		return ret;
 870
 871	/* Set row start and end */
 872	ret = ssd130x_write_cmd(ssd130x, 3, SSD132X_SET_ROW_RANGE, y, rows - 1);
 873	if (ret < 0)
 874		return ret;
 875
 876	for (i = 0; i < height; i++) {
 877		/* Process pair of pixels and combine them into a single byte */
 878		for (j = 0; j < width; j += segment_width) {
 879			u8 n1 = buf[i * width + j];
 880			u8 n2 = buf[i * width + j + 1];
 881
 882			data_array[array_idx++] = (n2 & 0xf0) | (n1 >> 4);
 883		}
 884	}
 885
 886	/* Write out update in one go since horizontal addressing mode is used */
 887	ret = ssd130x_write_data(ssd130x, data_array, columns * rows);
 888
 889	return ret;
 890}
 891
 892static int ssd133x_update_rect(struct ssd130x_device *ssd130x,
 893			       struct drm_rect *rect, u8 *data_array,
 894			       unsigned int pitch)
 895{
 896	unsigned int x = rect->x1;
 897	unsigned int y = rect->y1;
 898	unsigned int columns = drm_rect_width(rect);
 899	unsigned int rows = drm_rect_height(rect);
 900	int ret;
 901
 902	/*
 903	 * The screen is divided in Segment and Common outputs, where
 904	 * COM0 to COM[N - 1] are the rows and SEG0 to SEG[M - 1] are
 905	 * the columns.
 906	 *
 907	 * Each Segment has a 8-bit pixel and each Common output has a
 908	 * row of pixels. When using the (default) horizontal address
 909	 * increment mode, each byte of data sent to the controller has
 910	 * a Segment (e.g: SEG0).
 911	 *
 912	 * When using the 256 color depth format, each pixel contains 3
 913	 * sub-pixels for color A, B and C. These have 3 bit, 3 bit and
 914	 * 2 bits respectively.
 915	 */
 916
 917	/* Set column start and end */
 918	ret = ssd130x_write_cmd(ssd130x, 3, SSD133X_SET_COL_RANGE, x, columns - 1);
 919	if (ret < 0)
 920		return ret;
 921
 922	/* Set row start and end */
 923	ret = ssd130x_write_cmd(ssd130x, 3, SSD133X_SET_ROW_RANGE, y, rows - 1);
 924	if (ret < 0)
 925		return ret;
 926
 927	/* Write out update in one go since horizontal addressing mode is used */
 928	ret = ssd130x_write_data(ssd130x, data_array, pitch * rows);
 929
 930	return ret;
 931}
 932
 933static void ssd130x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
 934{
 935	unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
 936	unsigned int width = ssd130x->width;
 937	int ret, i;
 938
 939	if (!ssd130x->page_address_mode) {
 940		memset(data_array, 0, width * pages);
 941
 942		/* Set address range for horizontal addressing mode */
 943		ret = ssd130x_set_col_range(ssd130x, ssd130x->col_offset, width);
 944		if (ret < 0)
 945			return;
 946
 947		ret = ssd130x_set_page_range(ssd130x, ssd130x->page_offset, pages);
 948		if (ret < 0)
 949			return;
 950
 951		/* Write out update in one go if we aren't using page addressing mode */
 952		ssd130x_write_data(ssd130x, data_array, width * pages);
 953	} else {
 954		/*
 955		 * In page addressing mode, the start address needs to be reset,
 956		 * and each page then needs to be written out separately.
 957		 */
 958		memset(data_array, 0, width);
 959
 960		for (i = 0; i < pages; i++) {
 961			ret = ssd130x_set_page_pos(ssd130x,
 962						   ssd130x->page_offset + i,
 963						   ssd130x->col_offset);
 964			if (ret < 0)
 965				return;
 966
 967			ret = ssd130x_write_data(ssd130x, data_array, width);
 968			if (ret < 0)
 969				return;
 970		}
 971	}
 972}
 973
 974static void ssd132x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
 975{
 976	unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
 977	unsigned int height = ssd130x->height;
 978
 979	memset(data_array, 0, columns * height);
 980
 981	/* Write out update in one go since horizontal addressing mode is used */
 982	ssd130x_write_data(ssd130x, data_array, columns * height);
 983}
 984
 985static void ssd133x_clear_screen(struct ssd130x_device *ssd130x, u8 *data_array)
 986{
 987	const struct drm_format_info *fi = drm_format_info(DRM_FORMAT_RGB332);
 988	unsigned int pitch;
 989
 990	if (!fi)
 991		return;
 992
 993	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
 994
 995	memset(data_array, 0, pitch * ssd130x->height);
 996
 997	/* Write out update in one go since horizontal addressing mode is used */
 998	ssd130x_write_data(ssd130x, data_array, pitch * ssd130x->height);
 999}
1000
1001static int ssd130x_fb_blit_rect(struct drm_framebuffer *fb,
1002				const struct iosys_map *vmap,
1003				struct drm_rect *rect,
1004				u8 *buf, u8 *data_array,
1005				struct drm_format_conv_state *fmtcnv_state)
1006{
1007	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
1008	struct iosys_map dst;
1009	unsigned int dst_pitch;
1010	int ret = 0;
1011
1012	/* Align y to display page boundaries */
1013	rect->y1 = round_down(rect->y1, SSD130X_PAGE_HEIGHT);
1014	rect->y2 = min_t(unsigned int, round_up(rect->y2, SSD130X_PAGE_HEIGHT), ssd130x->height);
1015
1016	dst_pitch = DIV_ROUND_UP(drm_rect_width(rect), 8);
1017
1018	iosys_map_set_vaddr(&dst, buf);
1019	drm_fb_xrgb8888_to_mono(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
1020
1021	ssd130x_update_rect(ssd130x, rect, buf, data_array);
1022
1023	return ret;
1024}
1025
1026static int ssd132x_fb_blit_rect(struct drm_framebuffer *fb,
1027				const struct iosys_map *vmap,
1028				struct drm_rect *rect, u8 *buf,
1029				u8 *data_array,
1030				struct drm_format_conv_state *fmtcnv_state)
1031{
1032	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
1033	unsigned int dst_pitch;
1034	struct iosys_map dst;
1035	int ret = 0;
1036
1037	/* Align x to display segment boundaries */
1038	rect->x1 = round_down(rect->x1, SSD132X_SEGMENT_WIDTH);
1039	rect->x2 = min_t(unsigned int, round_up(rect->x2, SSD132X_SEGMENT_WIDTH),
1040			 ssd130x->width);
1041
1042	dst_pitch = drm_rect_width(rect);
1043
1044	iosys_map_set_vaddr(&dst, buf);
1045	drm_fb_xrgb8888_to_gray8(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
1046
1047	ssd132x_update_rect(ssd130x, rect, buf, data_array);
1048
1049	return ret;
1050}
1051
1052static int ssd133x_fb_blit_rect(struct drm_framebuffer *fb,
1053				const struct iosys_map *vmap,
1054				struct drm_rect *rect, u8 *data_array,
1055				struct drm_format_conv_state *fmtcnv_state)
1056{
1057	struct ssd130x_device *ssd130x = drm_to_ssd130x(fb->dev);
1058	const struct drm_format_info *fi = drm_format_info(DRM_FORMAT_RGB332);
1059	unsigned int dst_pitch;
1060	struct iosys_map dst;
1061	int ret = 0;
1062
1063	if (!fi)
1064		return -EINVAL;
1065
1066	dst_pitch = drm_format_info_min_pitch(fi, 0, drm_rect_width(rect));
1067
1068	iosys_map_set_vaddr(&dst, data_array);
1069	drm_fb_xrgb8888_to_rgb332(&dst, &dst_pitch, vmap, fb, rect, fmtcnv_state);
1070
1071	ssd133x_update_rect(ssd130x, rect, data_array, dst_pitch);
1072
1073	return ret;
1074}
1075
1076static int ssd130x_primary_plane_atomic_check(struct drm_plane *plane,
1077					      struct drm_atomic_state *state)
1078{
1079	struct drm_device *drm = plane->dev;
1080	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1081	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1082	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
1083	struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
1084	struct drm_crtc *crtc = plane_state->crtc;
1085	struct drm_crtc_state *crtc_state = NULL;
1086	const struct drm_format_info *fi;
1087	unsigned int pitch;
1088	int ret;
1089
1090	if (crtc)
1091		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1092
1093	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
1094						  DRM_PLANE_NO_SCALING,
1095						  DRM_PLANE_NO_SCALING,
1096						  false, false);
1097	if (ret)
1098		return ret;
1099	else if (!plane_state->visible)
1100		return 0;
1101
1102	fi = drm_format_info(DRM_FORMAT_R1);
1103	if (!fi)
1104		return -EINVAL;
1105
1106	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
1107
1108	if (plane_state->fb->format != fi) {
1109		void *buf;
1110
1111		/* format conversion necessary; reserve buffer */
1112		buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
1113						    pitch, GFP_KERNEL);
1114		if (!buf)
1115			return -ENOMEM;
1116	}
1117
1118	ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
1119	if (!ssd130x_state->buffer)
1120		return -ENOMEM;
1121
1122	return 0;
1123}
1124
1125static int ssd132x_primary_plane_atomic_check(struct drm_plane *plane,
1126					      struct drm_atomic_state *state)
1127{
1128	struct drm_device *drm = plane->dev;
1129	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1130	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1131	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(plane_state);
1132	struct drm_shadow_plane_state *shadow_plane_state = &ssd130x_state->base;
1133	struct drm_crtc *crtc = plane_state->crtc;
1134	struct drm_crtc_state *crtc_state = NULL;
1135	const struct drm_format_info *fi;
1136	unsigned int pitch;
1137	int ret;
1138
1139	if (crtc)
1140		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1141
1142	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
1143						  DRM_PLANE_NO_SCALING,
1144						  DRM_PLANE_NO_SCALING,
1145						  false, false);
1146	if (ret)
1147		return ret;
1148	else if (!plane_state->visible)
1149		return 0;
1150
1151	fi = drm_format_info(DRM_FORMAT_R8);
1152	if (!fi)
1153		return -EINVAL;
1154
1155	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
1156
1157	if (plane_state->fb->format != fi) {
1158		void *buf;
1159
1160		/* format conversion necessary; reserve buffer */
1161		buf = drm_format_conv_state_reserve(&shadow_plane_state->fmtcnv_state,
1162						    pitch, GFP_KERNEL);
1163		if (!buf)
1164			return -ENOMEM;
1165	}
1166
1167	ssd130x_state->buffer = kcalloc(pitch, ssd130x->height, GFP_KERNEL);
1168	if (!ssd130x_state->buffer)
1169		return -ENOMEM;
1170
1171	return 0;
1172}
1173
1174static int ssd133x_primary_plane_atomic_check(struct drm_plane *plane,
1175					      struct drm_atomic_state *state)
1176{
1177	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1178	struct drm_crtc *crtc = plane_state->crtc;
1179	struct drm_crtc_state *crtc_state = NULL;
1180	int ret;
1181
1182	if (crtc)
1183		crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1184
1185	ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
1186						  DRM_PLANE_NO_SCALING,
1187						  DRM_PLANE_NO_SCALING,
1188						  false, false);
1189	if (ret)
1190		return ret;
1191	else if (!plane_state->visible)
1192		return 0;
1193
1194	return 0;
1195}
1196
1197static void ssd130x_primary_plane_atomic_update(struct drm_plane *plane,
1198						struct drm_atomic_state *state)
1199{
1200	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1201	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
1202	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
1203	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1204	struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
1205	struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
1206	struct drm_framebuffer *fb = plane_state->fb;
1207	struct drm_atomic_helper_damage_iter iter;
1208	struct drm_device *drm = plane->dev;
1209	struct drm_rect dst_clip;
1210	struct drm_rect damage;
1211	int idx;
1212
1213	if (!drm_dev_enter(drm, &idx))
1214		return;
1215
1216	if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE))
1217		goto out_drm_dev_exit;
1218
1219	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
1220	drm_atomic_for_each_plane_damage(&iter, &damage) {
1221		dst_clip = plane_state->dst;
1222
1223		if (!drm_rect_intersect(&dst_clip, &damage))
1224			continue;
1225
1226		ssd130x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
1227				     ssd130x_plane_state->buffer,
1228				     ssd130x_crtc_state->data_array,
1229				     &shadow_plane_state->fmtcnv_state);
1230	}
1231
1232	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
1233
1234out_drm_dev_exit:
1235	drm_dev_exit(idx);
1236}
1237
1238static void ssd132x_primary_plane_atomic_update(struct drm_plane *plane,
1239						struct drm_atomic_state *state)
1240{
1241	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1242	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
1243	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
1244	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1245	struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
1246	struct ssd130x_plane_state *ssd130x_plane_state = to_ssd130x_plane_state(plane_state);
1247	struct drm_framebuffer *fb = plane_state->fb;
1248	struct drm_atomic_helper_damage_iter iter;
1249	struct drm_device *drm = plane->dev;
1250	struct drm_rect dst_clip;
1251	struct drm_rect damage;
1252	int idx;
1253
1254	if (!drm_dev_enter(drm, &idx))
1255		return;
1256
1257	if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE))
1258		goto out_drm_dev_exit;
1259
1260	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
1261	drm_atomic_for_each_plane_damage(&iter, &damage) {
1262		dst_clip = plane_state->dst;
1263
1264		if (!drm_rect_intersect(&dst_clip, &damage))
1265			continue;
1266
1267		ssd132x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
1268				     ssd130x_plane_state->buffer,
1269				     ssd130x_crtc_state->data_array,
1270				     &shadow_plane_state->fmtcnv_state);
1271	}
1272
1273	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
1274
1275out_drm_dev_exit:
1276	drm_dev_exit(idx);
1277}
1278
1279static void ssd133x_primary_plane_atomic_update(struct drm_plane *plane,
1280						struct drm_atomic_state *state)
1281{
1282	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1283	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
1284	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
1285	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1286	struct ssd130x_crtc_state *ssd130x_crtc_state =  to_ssd130x_crtc_state(crtc_state);
1287	struct drm_framebuffer *fb = plane_state->fb;
1288	struct drm_atomic_helper_damage_iter iter;
1289	struct drm_device *drm = plane->dev;
1290	struct drm_rect dst_clip;
1291	struct drm_rect damage;
1292	int idx;
1293
1294	if (!drm_dev_enter(drm, &idx))
1295		return;
1296
1297	if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE))
1298		goto out_drm_dev_exit;
1299
1300	drm_atomic_helper_damage_iter_init(&iter, old_plane_state, plane_state);
1301	drm_atomic_for_each_plane_damage(&iter, &damage) {
1302		dst_clip = plane_state->dst;
1303
1304		if (!drm_rect_intersect(&dst_clip, &damage))
1305			continue;
1306
1307		ssd133x_fb_blit_rect(fb, &shadow_plane_state->data[0], &dst_clip,
1308				     ssd130x_crtc_state->data_array,
1309				     &shadow_plane_state->fmtcnv_state);
1310	}
1311
1312	drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
1313
1314out_drm_dev_exit:
1315	drm_dev_exit(idx);
1316}
1317
1318static void ssd130x_primary_plane_atomic_disable(struct drm_plane *plane,
1319						 struct drm_atomic_state *state)
1320{
1321	struct drm_device *drm = plane->dev;
1322	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1323	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1324	struct drm_crtc_state *crtc_state;
1325	struct ssd130x_crtc_state *ssd130x_crtc_state;
1326	int idx;
1327
1328	if (!plane_state->crtc)
1329		return;
1330
1331	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1332	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1333
1334	if (!drm_dev_enter(drm, &idx))
1335		return;
1336
1337	ssd130x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1338
1339	drm_dev_exit(idx);
1340}
1341
1342static void ssd132x_primary_plane_atomic_disable(struct drm_plane *plane,
1343						 struct drm_atomic_state *state)
1344{
1345	struct drm_device *drm = plane->dev;
1346	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1347	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1348	struct drm_crtc_state *crtc_state;
1349	struct ssd130x_crtc_state *ssd130x_crtc_state;
1350	int idx;
1351
1352	if (!plane_state->crtc)
1353		return;
1354
1355	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1356	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1357
1358	if (!drm_dev_enter(drm, &idx))
1359		return;
1360
1361	ssd132x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1362
1363	drm_dev_exit(idx);
1364}
1365
1366static void ssd133x_primary_plane_atomic_disable(struct drm_plane *plane,
1367						 struct drm_atomic_state *state)
1368{
1369	struct drm_device *drm = plane->dev;
1370	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1371	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
1372	struct drm_crtc_state *crtc_state;
1373	struct ssd130x_crtc_state *ssd130x_crtc_state;
1374	int idx;
1375
1376	if (!plane_state->crtc)
1377		return;
1378
1379	crtc_state = drm_atomic_get_new_crtc_state(state, plane_state->crtc);
1380	ssd130x_crtc_state = to_ssd130x_crtc_state(crtc_state);
1381
1382	if (!drm_dev_enter(drm, &idx))
1383		return;
1384
1385	ssd133x_clear_screen(ssd130x, ssd130x_crtc_state->data_array);
1386
1387	drm_dev_exit(idx);
1388}
1389
1390/* Called during init to allocate the plane's atomic state. */
1391static void ssd130x_primary_plane_reset(struct drm_plane *plane)
1392{
1393	struct ssd130x_plane_state *ssd130x_state;
1394
1395	drm_WARN_ON_ONCE(plane->dev, plane->state);
1396
1397	ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1398	if (!ssd130x_state)
1399		return;
1400
1401	__drm_gem_reset_shadow_plane(plane, &ssd130x_state->base);
1402}
1403
1404static struct drm_plane_state *ssd130x_primary_plane_duplicate_state(struct drm_plane *plane)
1405{
1406	struct drm_shadow_plane_state *new_shadow_plane_state;
1407	struct ssd130x_plane_state *old_ssd130x_state;
1408	struct ssd130x_plane_state *ssd130x_state;
1409
1410	if (drm_WARN_ON_ONCE(plane->dev, !plane->state))
1411		return NULL;
1412
1413	old_ssd130x_state = to_ssd130x_plane_state(plane->state);
1414	ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1415	if (!ssd130x_state)
1416		return NULL;
1417
1418	/* The buffer is not duplicated and is allocated in .atomic_check */
1419	ssd130x_state->buffer = NULL;
1420
1421	new_shadow_plane_state = &ssd130x_state->base;
1422
1423	__drm_gem_duplicate_shadow_plane_state(plane, new_shadow_plane_state);
1424
1425	return &new_shadow_plane_state->base;
1426}
1427
1428static void ssd130x_primary_plane_destroy_state(struct drm_plane *plane,
1429						struct drm_plane_state *state)
1430{
1431	struct ssd130x_plane_state *ssd130x_state = to_ssd130x_plane_state(state);
1432
1433	kfree(ssd130x_state->buffer);
1434
1435	__drm_gem_destroy_shadow_plane_state(&ssd130x_state->base);
1436
1437	kfree(ssd130x_state);
1438}
1439
1440static const struct drm_plane_helper_funcs ssd130x_primary_plane_helper_funcs[] = {
1441	[SSD130X_FAMILY] = {
1442		DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1443		.atomic_check = ssd130x_primary_plane_atomic_check,
1444		.atomic_update = ssd130x_primary_plane_atomic_update,
1445		.atomic_disable = ssd130x_primary_plane_atomic_disable,
1446	},
1447	[SSD132X_FAMILY] = {
1448		DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1449		.atomic_check = ssd132x_primary_plane_atomic_check,
1450		.atomic_update = ssd132x_primary_plane_atomic_update,
1451		.atomic_disable = ssd132x_primary_plane_atomic_disable,
1452	},
1453	[SSD133X_FAMILY] = {
1454		DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
1455		.atomic_check = ssd133x_primary_plane_atomic_check,
1456		.atomic_update = ssd133x_primary_plane_atomic_update,
1457		.atomic_disable = ssd133x_primary_plane_atomic_disable,
1458	}
1459};
1460
1461static const struct drm_plane_funcs ssd130x_primary_plane_funcs = {
1462	.update_plane = drm_atomic_helper_update_plane,
1463	.disable_plane = drm_atomic_helper_disable_plane,
1464	.reset = ssd130x_primary_plane_reset,
1465	.atomic_duplicate_state = ssd130x_primary_plane_duplicate_state,
1466	.atomic_destroy_state = ssd130x_primary_plane_destroy_state,
1467	.destroy = drm_plane_cleanup,
1468};
1469
1470static enum drm_mode_status ssd130x_crtc_mode_valid(struct drm_crtc *crtc,
1471						    const struct drm_display_mode *mode)
1472{
1473	struct ssd130x_device *ssd130x = drm_to_ssd130x(crtc->dev);
1474
1475	return drm_crtc_helper_mode_valid_fixed(crtc, mode, &ssd130x->mode);
1476}
1477
1478static int ssd130x_crtc_atomic_check(struct drm_crtc *crtc,
1479				     struct drm_atomic_state *state)
1480{
1481	struct drm_device *drm = crtc->dev;
1482	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1483	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1484	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1485	unsigned int pages = DIV_ROUND_UP(ssd130x->height, SSD130X_PAGE_HEIGHT);
1486	int ret;
1487
1488	ret = drm_crtc_helper_atomic_check(crtc, state);
1489	if (ret)
1490		return ret;
1491
1492	ssd130x_state->data_array = kmalloc_array(ssd130x->width, pages, GFP_KERNEL);
1493	if (!ssd130x_state->data_array)
1494		return -ENOMEM;
1495
1496	return 0;
1497}
1498
1499static int ssd132x_crtc_atomic_check(struct drm_crtc *crtc,
1500				     struct drm_atomic_state *state)
1501{
1502	struct drm_device *drm = crtc->dev;
1503	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1504	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1505	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1506	unsigned int columns = DIV_ROUND_UP(ssd130x->width, SSD132X_SEGMENT_WIDTH);
1507	int ret;
1508
1509	ret = drm_crtc_helper_atomic_check(crtc, state);
1510	if (ret)
1511		return ret;
1512
1513	ssd130x_state->data_array = kmalloc_array(columns, ssd130x->height, GFP_KERNEL);
1514	if (!ssd130x_state->data_array)
1515		return -ENOMEM;
1516
1517	return 0;
1518}
1519
1520static int ssd133x_crtc_atomic_check(struct drm_crtc *crtc,
1521				     struct drm_atomic_state *state)
1522{
1523	struct drm_device *drm = crtc->dev;
1524	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1525	struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
1526	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(crtc_state);
1527	const struct drm_format_info *fi = drm_format_info(DRM_FORMAT_RGB332);
1528	unsigned int pitch;
1529	int ret;
1530
1531	if (!fi)
1532		return -EINVAL;
1533
1534	ret = drm_crtc_helper_atomic_check(crtc, state);
1535	if (ret)
1536		return ret;
1537
1538	pitch = drm_format_info_min_pitch(fi, 0, ssd130x->width);
1539
1540	ssd130x_state->data_array = kmalloc_array(pitch, ssd130x->height, GFP_KERNEL);
1541	if (!ssd130x_state->data_array)
1542		return -ENOMEM;
1543
1544	return 0;
1545}
1546
1547/* Called during init to allocate the CRTC's atomic state. */
1548static void ssd130x_crtc_reset(struct drm_crtc *crtc)
1549{
1550	struct ssd130x_crtc_state *ssd130x_state;
1551
1552	drm_WARN_ON_ONCE(crtc->dev, crtc->state);
1553
1554	ssd130x_state = kzalloc(sizeof(*ssd130x_state), GFP_KERNEL);
1555	if (!ssd130x_state)
1556		return;
1557
1558	__drm_atomic_helper_crtc_reset(crtc, &ssd130x_state->base);
1559}
1560
1561static struct drm_crtc_state *ssd130x_crtc_duplicate_state(struct drm_crtc *crtc)
1562{
1563	struct ssd130x_crtc_state *old_ssd130x_state;
1564	struct ssd130x_crtc_state *ssd130x_state;
1565
1566	if (drm_WARN_ON_ONCE(crtc->dev, !crtc->state))
1567		return NULL;
1568
1569	old_ssd130x_state = to_ssd130x_crtc_state(crtc->state);
1570	ssd130x_state = kmemdup(old_ssd130x_state, sizeof(*ssd130x_state), GFP_KERNEL);
1571	if (!ssd130x_state)
1572		return NULL;
1573
1574	/* The buffer is not duplicated and is allocated in .atomic_check */
1575	ssd130x_state->data_array = NULL;
1576
1577	__drm_atomic_helper_crtc_duplicate_state(crtc, &ssd130x_state->base);
1578
1579	return &ssd130x_state->base;
1580}
1581
1582static void ssd130x_crtc_destroy_state(struct drm_crtc *crtc,
1583				       struct drm_crtc_state *state)
1584{
1585	struct ssd130x_crtc_state *ssd130x_state = to_ssd130x_crtc_state(state);
1586
1587	kfree(ssd130x_state->data_array);
1588
1589	__drm_atomic_helper_crtc_destroy_state(state);
1590
1591	kfree(ssd130x_state);
1592}
1593
1594/*
1595 * The CRTC is always enabled. Screen updates are performed by
1596 * the primary plane's atomic_update function. Disabling clears
1597 * the screen in the primary plane's atomic_disable function.
1598 */
1599static const struct drm_crtc_helper_funcs ssd130x_crtc_helper_funcs[] = {
1600	[SSD130X_FAMILY] = {
1601		.mode_valid = ssd130x_crtc_mode_valid,
1602		.atomic_check = ssd130x_crtc_atomic_check,
1603	},
1604	[SSD132X_FAMILY] = {
1605		.mode_valid = ssd130x_crtc_mode_valid,
1606		.atomic_check = ssd132x_crtc_atomic_check,
1607	},
1608	[SSD133X_FAMILY] = {
1609		.mode_valid = ssd130x_crtc_mode_valid,
1610		.atomic_check = ssd133x_crtc_atomic_check,
1611	},
1612};
1613
1614static const struct drm_crtc_funcs ssd130x_crtc_funcs = {
1615	.reset = ssd130x_crtc_reset,
1616	.destroy = drm_crtc_cleanup,
1617	.set_config = drm_atomic_helper_set_config,
1618	.page_flip = drm_atomic_helper_page_flip,
1619	.atomic_duplicate_state = ssd130x_crtc_duplicate_state,
1620	.atomic_destroy_state = ssd130x_crtc_destroy_state,
1621};
1622
1623static void ssd130x_encoder_atomic_enable(struct drm_encoder *encoder,
1624					  struct drm_atomic_state *state)
1625{
1626	struct drm_device *drm = encoder->dev;
1627	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1628	int ret;
1629
1630	ret = ssd130x_power_on(ssd130x);
1631	if (ret)
1632		return;
1633
1634	ret = ssd130x_init(ssd130x);
1635	if (ret)
1636		goto power_off;
1637
1638	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1639
1640	backlight_enable(ssd130x->bl_dev);
1641
1642	return;
1643
1644power_off:
1645	ssd130x_power_off(ssd130x);
1646	return;
1647}
1648
1649static void ssd132x_encoder_atomic_enable(struct drm_encoder *encoder,
1650					  struct drm_atomic_state *state)
1651{
1652	struct drm_device *drm = encoder->dev;
1653	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1654	int ret;
1655
1656	ret = ssd130x_power_on(ssd130x);
1657	if (ret)
1658		return;
1659
1660	ret = ssd132x_init(ssd130x);
1661	if (ret)
1662		goto power_off;
1663
1664	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1665
1666	backlight_enable(ssd130x->bl_dev);
1667
1668	return;
1669
1670power_off:
1671	ssd130x_power_off(ssd130x);
1672}
1673
1674static void ssd133x_encoder_atomic_enable(struct drm_encoder *encoder,
1675					  struct drm_atomic_state *state)
1676{
1677	struct drm_device *drm = encoder->dev;
1678	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1679	int ret;
1680
1681	ret = ssd130x_power_on(ssd130x);
1682	if (ret)
1683		return;
1684
1685	ret = ssd133x_init(ssd130x);
1686	if (ret)
1687		goto power_off;
1688
1689	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_ON);
1690
1691	backlight_enable(ssd130x->bl_dev);
1692
1693	return;
1694
1695power_off:
1696	ssd130x_power_off(ssd130x);
1697}
1698
1699static void ssd130x_encoder_atomic_disable(struct drm_encoder *encoder,
1700					   struct drm_atomic_state *state)
1701{
1702	struct drm_device *drm = encoder->dev;
1703	struct ssd130x_device *ssd130x = drm_to_ssd130x(drm);
1704
1705	backlight_disable(ssd130x->bl_dev);
1706
1707	ssd130x_write_cmd(ssd130x, 1, SSD13XX_DISPLAY_OFF);
1708
1709	ssd130x_power_off(ssd130x);
1710}
1711
1712static const struct drm_encoder_helper_funcs ssd130x_encoder_helper_funcs[] = {
1713	[SSD130X_FAMILY] = {
1714		.atomic_enable = ssd130x_encoder_atomic_enable,
1715		.atomic_disable = ssd130x_encoder_atomic_disable,
1716	},
1717	[SSD132X_FAMILY] = {
1718		.atomic_enable = ssd132x_encoder_atomic_enable,
1719		.atomic_disable = ssd130x_encoder_atomic_disable,
1720	},
1721	[SSD133X_FAMILY] = {
1722		.atomic_enable = ssd133x_encoder_atomic_enable,
1723		.atomic_disable = ssd130x_encoder_atomic_disable,
1724	}
1725};
1726
1727static const struct drm_encoder_funcs ssd130x_encoder_funcs = {
1728	.destroy = drm_encoder_cleanup,
1729};
1730
1731static int ssd130x_connector_get_modes(struct drm_connector *connector)
1732{
1733	struct ssd130x_device *ssd130x = drm_to_ssd130x(connector->dev);
1734
1735	return drm_connector_helper_get_modes_fixed(connector, &ssd130x->mode);
1736}
1737
1738static const struct drm_connector_helper_funcs ssd130x_connector_helper_funcs = {
1739	.get_modes = ssd130x_connector_get_modes,
1740};
1741
1742static const struct drm_connector_funcs ssd130x_connector_funcs = {
1743	.reset = drm_atomic_helper_connector_reset,
1744	.fill_modes = drm_helper_probe_single_connector_modes,
1745	.destroy = drm_connector_cleanup,
1746	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
1747	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
1748};
1749
1750static const struct drm_mode_config_funcs ssd130x_mode_config_funcs = {
1751	.fb_create = drm_gem_fb_create_with_dirty,
1752	.atomic_check = drm_atomic_helper_check,
1753	.atomic_commit = drm_atomic_helper_commit,
1754};
1755
1756static const uint32_t ssd130x_formats[] = {
1757	DRM_FORMAT_XRGB8888,
1758};
1759
1760DEFINE_DRM_GEM_FOPS(ssd130x_fops);
1761
1762static const struct drm_driver ssd130x_drm_driver = {
1763	DRM_GEM_SHMEM_DRIVER_OPS,
1764	DRM_FBDEV_SHMEM_DRIVER_OPS,
1765	.name			= DRIVER_NAME,
1766	.desc			= DRIVER_DESC,
1767	.major			= DRIVER_MAJOR,
1768	.minor			= DRIVER_MINOR,
1769	.driver_features	= DRIVER_ATOMIC | DRIVER_GEM | DRIVER_MODESET,
1770	.fops			= &ssd130x_fops,
1771};
1772
1773static int ssd130x_update_bl(struct backlight_device *bdev)
1774{
1775	struct ssd130x_device *ssd130x = bl_get_data(bdev);
1776	int brightness = backlight_get_brightness(bdev);
1777	int ret;
1778
1779	ssd130x->contrast = brightness;
1780
1781	ret = ssd130x_write_cmd(ssd130x, 1, SSD13XX_CONTRAST);
1782	if (ret < 0)
1783		return ret;
1784
1785	ret = ssd130x_write_cmd(ssd130x, 1, ssd130x->contrast);
1786	if (ret < 0)
1787		return ret;
1788
1789	return 0;
1790}
1791
1792static const struct backlight_ops ssd130xfb_bl_ops = {
1793	.update_status	= ssd130x_update_bl,
1794};
1795
1796static void ssd130x_parse_properties(struct ssd130x_device *ssd130x)
1797{
1798	struct device *dev = ssd130x->dev;
1799
1800	if (device_property_read_u32(dev, "solomon,width", &ssd130x->width))
1801		ssd130x->width = ssd130x->device_info->default_width;
1802
1803	if (device_property_read_u32(dev, "solomon,height", &ssd130x->height))
1804		ssd130x->height = ssd130x->device_info->default_height;
1805
1806	if (device_property_read_u32(dev, "solomon,page-offset", &ssd130x->page_offset))
1807		ssd130x->page_offset = 1;
1808
1809	if (device_property_read_u32(dev, "solomon,col-offset", &ssd130x->col_offset))
1810		ssd130x->col_offset = 0;
1811
1812	if (device_property_read_u32(dev, "solomon,com-offset", &ssd130x->com_offset))
1813		ssd130x->com_offset = 0;
1814
1815	if (device_property_read_u32(dev, "solomon,prechargep1", &ssd130x->prechargep1))
1816		ssd130x->prechargep1 = 2;
1817
1818	if (device_property_read_u32(dev, "solomon,prechargep2", &ssd130x->prechargep2))
1819		ssd130x->prechargep2 = 2;
1820
1821	if (!device_property_read_u8_array(dev, "solomon,lookup-table",
1822					   ssd130x->lookup_table,
1823					   ARRAY_SIZE(ssd130x->lookup_table)))
1824		ssd130x->lookup_table_set = 1;
1825
1826	ssd130x->seg_remap = !device_property_read_bool(dev, "solomon,segment-no-remap");
1827	ssd130x->com_seq = device_property_read_bool(dev, "solomon,com-seq");
1828	ssd130x->com_lrremap = device_property_read_bool(dev, "solomon,com-lrremap");
1829	ssd130x->com_invdir = device_property_read_bool(dev, "solomon,com-invdir");
1830	ssd130x->area_color_enable =
1831		device_property_read_bool(dev, "solomon,area-color-enable");
1832	ssd130x->low_power = device_property_read_bool(dev, "solomon,low-power");
1833
1834	ssd130x->contrast = 127;
1835	ssd130x->vcomh = ssd130x->device_info->default_vcomh;
1836
1837	/* Setup display timing */
1838	if (device_property_read_u32(dev, "solomon,dclk-div", &ssd130x->dclk_div))
1839		ssd130x->dclk_div = ssd130x->device_info->default_dclk_div;
1840	if (device_property_read_u32(dev, "solomon,dclk-frq", &ssd130x->dclk_frq))
1841		ssd130x->dclk_frq = ssd130x->device_info->default_dclk_frq;
1842}
1843
1844static int ssd130x_init_modeset(struct ssd130x_device *ssd130x)
1845{
1846	enum ssd130x_family_ids family_id = ssd130x->device_info->family_id;
1847	struct drm_display_mode *mode = &ssd130x->mode;
1848	struct device *dev = ssd130x->dev;
1849	struct drm_device *drm = &ssd130x->drm;
1850	unsigned long max_width, max_height;
1851	struct drm_plane *primary_plane;
1852	struct drm_crtc *crtc;
1853	struct drm_encoder *encoder;
1854	struct drm_connector *connector;
1855	int ret;
1856
1857	/*
1858	 * Modesetting
1859	 */
1860
1861	ret = drmm_mode_config_init(drm);
1862	if (ret) {
1863		dev_err(dev, "DRM mode config init failed: %d\n", ret);
1864		return ret;
1865	}
1866
1867	mode->type = DRM_MODE_TYPE_DRIVER;
1868	mode->clock = 1;
1869	mode->hdisplay = ssd130x->width;
1870	mode->htotal = ssd130x->width;
1871	mode->hsync_start = ssd130x->width;
1872	mode->hsync_end = ssd130x->width;
1873	mode->vdisplay = ssd130x->height;
1874	mode->vtotal = ssd130x->height;
1875	mode->vsync_start = ssd130x->height;
1876	mode->vsync_end = ssd130x->height;
1877	mode->width_mm = 27;
1878	mode->height_mm = 27;
1879
1880	max_width = max_t(unsigned long, mode->hdisplay, DRM_SHADOW_PLANE_MAX_WIDTH);
1881	max_height = max_t(unsigned long, mode->vdisplay, DRM_SHADOW_PLANE_MAX_HEIGHT);
1882
1883	drm->mode_config.min_width = mode->hdisplay;
1884	drm->mode_config.max_width = max_width;
1885	drm->mode_config.min_height = mode->vdisplay;
1886	drm->mode_config.max_height = max_height;
1887	drm->mode_config.preferred_depth = 24;
1888	drm->mode_config.funcs = &ssd130x_mode_config_funcs;
1889
1890	/* Primary plane */
1891
1892	primary_plane = &ssd130x->primary_plane;
1893	ret = drm_universal_plane_init(drm, primary_plane, 0, &ssd130x_primary_plane_funcs,
1894				       ssd130x_formats, ARRAY_SIZE(ssd130x_formats),
1895				       NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
1896	if (ret) {
1897		dev_err(dev, "DRM primary plane init failed: %d\n", ret);
1898		return ret;
1899	}
1900
1901	drm_plane_helper_add(primary_plane, &ssd130x_primary_plane_helper_funcs[family_id]);
1902
1903	drm_plane_enable_fb_damage_clips(primary_plane);
1904
1905	/* CRTC */
1906
1907	crtc = &ssd130x->crtc;
1908	ret = drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL,
1909					&ssd130x_crtc_funcs, NULL);
1910	if (ret) {
1911		dev_err(dev, "DRM crtc init failed: %d\n", ret);
1912		return ret;
1913	}
1914
1915	drm_crtc_helper_add(crtc, &ssd130x_crtc_helper_funcs[family_id]);
1916
1917	/* Encoder */
1918
1919	encoder = &ssd130x->encoder;
1920	ret = drm_encoder_init(drm, encoder, &ssd130x_encoder_funcs,
1921			       DRM_MODE_ENCODER_NONE, NULL);
1922	if (ret) {
1923		dev_err(dev, "DRM encoder init failed: %d\n", ret);
1924		return ret;
1925	}
1926
1927	drm_encoder_helper_add(encoder, &ssd130x_encoder_helper_funcs[family_id]);
1928
1929	encoder->possible_crtcs = drm_crtc_mask(crtc);
1930
1931	/* Connector */
1932
1933	connector = &ssd130x->connector;
1934	ret = drm_connector_init(drm, connector, &ssd130x_connector_funcs,
1935				 DRM_MODE_CONNECTOR_Unknown);
1936	if (ret) {
1937		dev_err(dev, "DRM connector init failed: %d\n", ret);
1938		return ret;
1939	}
1940
1941	drm_connector_helper_add(connector, &ssd130x_connector_helper_funcs);
1942
1943	ret = drm_connector_attach_encoder(connector, encoder);
1944	if (ret) {
1945		dev_err(dev, "DRM attach connector to encoder failed: %d\n", ret);
1946		return ret;
1947	}
1948
1949	drm_mode_config_reset(drm);
1950
1951	return 0;
1952}
1953
1954static int ssd130x_get_resources(struct ssd130x_device *ssd130x)
1955{
1956	struct device *dev = ssd130x->dev;
1957
1958	ssd130x->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
1959	if (IS_ERR(ssd130x->reset))
1960		return dev_err_probe(dev, PTR_ERR(ssd130x->reset),
1961				     "Failed to get reset gpio\n");
1962
1963	ssd130x->vcc_reg = devm_regulator_get(dev, "vcc");
1964	if (IS_ERR(ssd130x->vcc_reg))
1965		return dev_err_probe(dev, PTR_ERR(ssd130x->vcc_reg),
1966				     "Failed to get VCC regulator\n");
1967
1968	return 0;
1969}
1970
1971struct ssd130x_device *ssd130x_probe(struct device *dev, struct regmap *regmap)
1972{
1973	struct ssd130x_device *ssd130x;
1974	struct backlight_device *bl;
1975	struct drm_device *drm;
1976	int ret;
1977
1978	ssd130x = devm_drm_dev_alloc(dev, &ssd130x_drm_driver,
1979				     struct ssd130x_device, drm);
1980	if (IS_ERR(ssd130x))
1981		return ERR_PTR(dev_err_probe(dev, PTR_ERR(ssd130x),
1982					     "Failed to allocate DRM device\n"));
1983
1984	drm = &ssd130x->drm;
1985
1986	ssd130x->dev = dev;
1987	ssd130x->regmap = regmap;
1988	ssd130x->device_info = device_get_match_data(dev);
1989
1990	if (ssd130x->device_info->page_mode_only)
1991		ssd130x->page_address_mode = 1;
1992
1993	ssd130x_parse_properties(ssd130x);
1994
1995	ret = ssd130x_get_resources(ssd130x);
1996	if (ret)
1997		return ERR_PTR(ret);
1998
1999	bl = devm_backlight_device_register(dev, dev_name(dev), dev, ssd130x,
2000					    &ssd130xfb_bl_ops, NULL);
2001	if (IS_ERR(bl))
2002		return ERR_PTR(dev_err_probe(dev, PTR_ERR(bl),
2003					     "Unable to register backlight device\n"));
2004
2005	bl->props.brightness = ssd130x->contrast;
2006	bl->props.max_brightness = MAX_CONTRAST;
2007	ssd130x->bl_dev = bl;
2008
2009	ret = ssd130x_init_modeset(ssd130x);
2010	if (ret)
2011		return ERR_PTR(ret);
2012
2013	ret = drm_dev_register(drm, 0);
2014	if (ret)
2015		return ERR_PTR(dev_err_probe(dev, ret, "DRM device register failed\n"));
2016
2017	drm_client_setup(drm, NULL);
2018
2019	return ssd130x;
2020}
2021EXPORT_SYMBOL_GPL(ssd130x_probe);
2022
2023void ssd130x_remove(struct ssd130x_device *ssd130x)
2024{
2025	drm_dev_unplug(&ssd130x->drm);
2026	drm_atomic_helper_shutdown(&ssd130x->drm);
2027}
2028EXPORT_SYMBOL_GPL(ssd130x_remove);
2029
2030void ssd130x_shutdown(struct ssd130x_device *ssd130x)
2031{
2032	drm_atomic_helper_shutdown(&ssd130x->drm);
2033}
2034EXPORT_SYMBOL_GPL(ssd130x_shutdown);
2035
2036MODULE_DESCRIPTION(DRIVER_DESC);
2037MODULE_AUTHOR("Javier Martinez Canillas <javierm@redhat.com>");
2038MODULE_LICENSE("GPL v2");
~/ Read-only file preview.