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
This commit is contained in:
parent
083a6c23b9
commit
d23d4d4dac
9 changed files with 57 additions and 87 deletions
|
@ -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:
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 = {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Add table
Reference in a new issue