1
0
Fork 0

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: Sam Ravnborg <sam@ravnborg.org>
Acked-by: : David Lechner <david@lechnology.com>
Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20190719155916.62465-8-noralf@tronnes.org
alistair/sunxi64-5.4-dsi
Noralf Trønnes 2019-07-19 17:59:12 +02:00
parent 083a6c23b9
commit d23d4d4dac
9 changed files with 57 additions and 87 deletions

View File

@ -11,9 +11,6 @@ Helpers
.. kernel-doc:: include/drm/tinydrm/tinydrm-helpers.h .. kernel-doc:: include/drm/tinydrm/tinydrm-helpers.h
:internal: :internal:
.. kernel-doc:: drivers/gpu/drm/tinydrm/core/tinydrm-helpers.c
:export:
.. kernel-doc:: drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c .. kernel-doc:: drivers/gpu/drm/tinydrm/core/tinydrm-pipe.c
:export: :export:

View File

@ -443,9 +443,6 @@ tinydrm
Tinydrm is the helper driver for really simple fb drivers. The goal is to make 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: 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 - 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 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 one of the ideas for having a shared dsi/dbi helper, abstracting away the

View File

@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0-only # 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 obj-$(CONFIG_DRM_TINYDRM) += tinydrm.o

View File

@ -1,70 +0,0 @@
// 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");

View File

@ -3,6 +3,8 @@
* Copyright (C) 2016 Noralf Trønnes * Copyright (C) 2016 Noralf Trønnes
*/ */
#include <linux/module.h>
#include <drm/drm_atomic_helper.h> #include <drm/drm_atomic_helper.h>
#include <drm/drm_drv.h> #include <drm/drm_drv.h>
#include <drm/drm_gem_framebuffer_helper.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); format_count, modifiers, connector);
} }
EXPORT_SYMBOL(tinydrm_display_pipe_init); EXPORT_SYMBOL(tinydrm_display_pipe_init);
MODULE_LICENSE("GPL");

View File

@ -27,7 +27,6 @@
#include <drm/drm_rect.h> #include <drm/drm_rect.h>
#include <drm/drm_vblank.h> #include <drm/drm_vblank.h>
#include <drm/tinydrm/mipi-dbi.h> #include <drm/tinydrm/mipi-dbi.h>
#include <drm/tinydrm/tinydrm-helpers.h>
#define ILI9225_DRIVER_READ_CODE 0x00 #define ILI9225_DRIVER_READ_CODE 0x00
#define ILI9225_DRIVER_OUTPUT_CONTROL 0x01 #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); gpiod_set_value_cansleep(mipi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); 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) if (ret || !num)
return ret; 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); gpiod_set_value_cansleep(mipi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); 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 = { static const struct drm_simple_display_pipe_funcs ili9225_pipe_funcs = {

View File

@ -926,7 +926,7 @@ static int mipi_dbi_typec3_command(struct mipi_dbi *mipi, u8 *cmd,
gpiod_set_value_cansleep(mipi->dc, 0); gpiod_set_value_cansleep(mipi->dc, 0);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, 1); 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) if (ret || !num)
return ret; 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); gpiod_set_value_cansleep(mipi->dc, 1);
speed_hz = mipi_dbi_spi_cmd_max_speed(spi, num); 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); 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 */ #endif /* CONFIG_SPI */
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS

View File

@ -83,7 +83,10 @@ void mipi_dbi_hw_reset(struct mipi_dbi *mipi);
bool mipi_dbi_display_is_on(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_reset(struct mipi_dbi *mipi);
int mipi_dbi_poweron_conditional_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); 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_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); int mipi_dbi_command_buf(struct mipi_dbi *mipi, u8 cmd, u8 *data, size_t len);

View File

@ -13,8 +13,6 @@ struct drm_framebuffer;
struct drm_rect; struct drm_rect;
struct drm_simple_display_pipe; struct drm_simple_display_pipe;
struct drm_simple_display_pipe_funcs; struct drm_simple_display_pipe_funcs;
struct spi_transfer;
struct spi_device;
struct device; struct device;
/** /**
@ -41,7 +39,4 @@ int tinydrm_display_pipe_init(struct drm_device *drm,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
unsigned int rotation); 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 */ #endif /* __LINUX_TINYDRM_HELPERS_H */