Linux Audio

Check our new training course

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