Commit d23d4d4d authored by Noralf Trønnes's avatar Noralf Trønnes

drm/tinydrm: Move tinydrm_spi_transfer()

This is only used by mipi-dbi drivers so move it there.

The reason this isn't moved to the SPI subsystem is that it will in a
later patch pass a dummy rx buffer for SPI controllers that need this.
Low memory boards (64MB) can run into a problem allocating such a "large"
contiguous buffer on every transfer after a long up time.
This leaves a very specific use case, so we'll keep the function here.
mipi-dbi will first go through a refactoring though, before this will
be done.

Remove SPI todo entry now that we're done with the tinydrm.ko SPI code.

v2: Drop moving the mipi_dbi_spi_init() declaration (Sam)

Cc: David Lechner <david@lechnology.com>
Reviewed-by: default avatarSam Ravnborg <sam@ravnborg.org>
Acked-by: default avatar: David Lechner <david@lechnology.com>
Signed-off-by: default avatarNoralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190719155916.62465-8-noralf@tronnes.org
parent 083a6c23
......@@ -11,9 +11,6 @@ Helpers
.. kernel-doc:: include/drm/tinydrm/tinydrm-helpers.h
:internal:
.. kernel-doc:: drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
:export:
.. kernel-doc:: drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
:export:
......
......@@ -443,9 +443,6 @@ tinydrm
Tinydrm is the helper driver for really simple fb drivers. The goal is to make
those drivers as simple as possible, so lots of room for refactoring:
- spi helpers, probably best put into spi core/helper code. Thierry said
the spi maintainer is fast&reactive, so shouldn't be a big issue.
- extract the mipi-dbi helper (well, the non-tinydrm specific parts at
least) into a separate helper, like we have for mipi-dsi already. Or follow
one of the ideas for having a shared dsi/dbi helper, abstracting away the
......
# SPDX-License-Identifier: GPL-2.0-only
tinydrm-y := tinydrm-pipe.o tinydrm-helpers.o
tinydrm-y := tinydrm-pipe.o
obj-$(CONFIG_DRM_TINYDRM) += tinydrm.o
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016 Noralf Trønnes
*/
#include <linux/backlight.h>
#include <linux/dma-buf.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/swab.h>
#include <drm/drm_device.h>
#include <drm/drm_drv.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_print.h>
#include <drm/drm_rect.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#if IS_ENABLED(CONFIG_SPI)
/**
* tinydrm_spi_transfer - SPI transfer helper
* @spi: SPI device
* @speed_hz: Override speed (optional)
* @bpw: Bits per word
* @buf: Buffer to transfer
* @len: Buffer length
*
* This SPI transfer helper breaks up the transfer of @buf into chunks which
* the SPI controller driver can handle.
*
* Returns:
* Zero on success, negative error code on failure.
*/
int tinydrm_spi_transfer(struct spi_device *spi, u32 speed_hz,
u8 bpw, const void *buf, size_t len)
{
size_t max_chunk = spi_max_transfer_size(spi);
struct spi_transfer tr = {
.bits_per_word = bpw,
.speed_hz = speed_hz,
};
struct spi_message m;
size_t chunk;
int ret;
spi_message_init_with_transfers(&m, &tr, 1);
while (len) {
chunk = min(len, max_chunk);
tr.tx_buf = buf;
tr.len = chunk;
buf += chunk;
len -= chunk;
ret = spi_sync(spi, &m);
if (ret)
return ret;
}
return 0;
}
EXPORT_SYMBOL(tinydrm_spi_transfer);
#endif /* CONFIG_SPI */
MODULE_LICENSE("GPL");
......@@ -3,6 +3,8 @@
* Copyright (C) 2016 Noralf Trønnes
*/
#include <linux/module.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_gem_framebuffer_helper.h>
......@@ -177,3 +179,5 @@ int tinydrm_display_pipe_init(struct drm_device *drm,
format_count, modifiers, connector);
}
EXPORT_SYMBOL(tinydrm_display_pipe_init);
MODULE_LICENSE("GPL");
......@@ -27,7 +27,6 @@
#include <drm/drm_rect.h>
#include <drm/drm_vblank.h>
#include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#define ILI9225_DRIVER_READ_CODE 0x00
#define ILI9225_DRIVER_OUTPUT_CONTROL 0x01
......@@ -323,7 +322,7 @@ static int ili9225_dbi_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
gpiod_set_value_cansleep(mipi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
ret = tinydrm_spi_transfer(spi, speed_hz, 8, cmd, 1);
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
if (ret || !num)
return ret;
......@@ -333,7 +332,7 @@ static int ili9225_dbi_command(struct mipi_dbi *mipi, u8 *cmd, u8 *par,
gpiod_set_value_cansleep(mipi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
return tinydrm_spi_transfer(spi, speed_hz, bpw, par, num);
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
}
static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = {
......
......@@ -926,7 +926,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 *cmd,
gpiod_set_value_cansleep(mipi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1);
ret = tinydrm_spi_transfer(spi, speed_hz, 8, cmd, 1);
ret = mipi_dbi_spi_transfer(spi, speed_hz, 8, cmd, 1);
if (ret || !num)
return ret;
......@@ -936,7 +936,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 *cmd,
gpiod_set_value_cansleep(mipi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num);
return tinydrm_spi_transfer(spi, speed_hz, bpw, par, num);
return mipi_dbi_spi_transfer(spi, speed_hz, bpw, par, num);
}
/**
......@@ -1007,6 +1007,51 @@ int mipi_dbi_spi_init(struct spi_device *spi, struct mipi_dbi *mipi,
}
EXPORT_SYMBOL(mipi_dbi_spi_init);
/**
* mipi_dbi_spi_transfer - SPI transfer helper
* @spi: SPI device
* @speed_hz: Override speed (optional)
* @bpw: Bits per word
* @buf: Buffer to transfer
* @len: Buffer length
*
* This SPI transfer helper breaks up the transfer of @buf into chunks which
* the SPI controller driver can handle.
*
* Returns:
* Zero on success, negative error code on failure.
*/
int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
u8 bpw, const void *buf, size_t len)
{
size_t max_chunk = spi_max_transfer_size(spi);
struct spi_transfer tr = {
.bits_per_word = bpw,
.speed_hz = speed_hz,
};
struct spi_message m;
size_t chunk;
int ret;
spi_message_init_with_transfers(&m, &tr, 1);
while (len) {
chunk = min(len, max_chunk);
tr.tx_buf = buf;
tr.len = chunk;
buf += chunk;
len -= chunk;
ret = spi_sync(spi, &m);
if (ret)
return ret;
}
return 0;
}
EXPORT_SYMBOL(mipi_dbi_spi_transfer);
#endif /* CONFIG_SPI */
#ifdef CONFIG_DEBUG_FS
......
......@@ -83,7 +83,10 @@ void mipi_dbi_hw_reset(struct mipi_dbi *mipi);
bool mipi_dbi_display_is_on(struct mipi_dbi *mipi);
int mipi_dbi_poweron_reset(struct mipi_dbi *mipi);
int mipi_dbi_poweron_conditional_reset(struct mipi_dbi *mipi);
u32 mipi_dbi_spi_cmd_max_speed(struct spi_device *spi, size_t len);
int mipi_dbi_spi_transfer(struct spi_device *spi, u32 speed_hz,
u8 bpw, const void *buf, size_t len);
int mipi_dbi_command_read(struct mipi_dbi *mipi, u8 cmd, u8 *val);
int mipi_dbi_command_buf(struct mipi_dbi *mipi, u8 cmd, u8 *data, size_t len);
......
......@@ -13,8 +13,6 @@ struct drm_framebuffer;
struct drm_rect;
struct drm_simple_display_pipe;
struct drm_simple_display_pipe_funcs;
struct spi_transfer;
struct spi_device;
struct device;
/**
......@@ -41,7 +39,4 @@ int tinydrm_display_pipe_init(struct drm_device *drm,
const struct drm_display_mode *mode,
unsigned int rotation);
int tinydrm_spi_transfer(struct spi_device *spi, u32 speed_hz,
u8 bpw, const void *buf, size_t len);
#endif /* __LINUX_TINYDRM_HELPERS_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment