tilcdc fixes for v4.9
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXyIizAAoJEJA2s1DX1hlBo8cP/0vc+JVWGV3+hGT1WlJs16nI bU+IywJO4gV1vgnui9uIFBx650c3Rv3a9lUhORO2RCWtgSOElyXco1zjr9ujUHnl LnqZPhQnsPHxx14pJ0MKiMpUKwWwzVcstRVzo/nHbixNgmKhjmKIS6JxpI8a+YRs cMCdqaG/2nRmVIDpmbTOoQmZY5FYcIjEpZbUWHFXq6TSZG3q9GgdJp97jqwn7bX/ MsowD5789ogGOFA3b7kmLG5AkX1EMsT09m5k3oDaP6XcWYG8Ir58tFcyo3MvaaBj Hk+9mqg9Y8NIHtGIz9QuwJJnxQNS2ATHVMJeRXlwgL4A/VwoEnW7YK7AvxqAatDL WhKGWBOr/A8YQhRhIE6JCRxvz793w9cT86j4Yh/OL77iXjKLGrQFBIbaAy69SEq6 BDYlLwf+wAaIsr0TPFZjcylOAnEjtZDSJU+B/Z+D9zFb+miJEGcuNfAq9yCJPdYb gMj8hPg/5JAp4fLShvwsDW5GuLFAUL2yL2YAhqKTjFbmrXsRIaYs4iievxezrdss LqdhKJVCYYy80+KgC6Aq3JR2KrnkWlL2lACrzvcQiBIdtddheHgP9f9ys9f8XeFf pEt7PMIN1174Q70Zo/lvvUrHOS8lBoJQPubY/u7VZKgDI+A7P+g2/NO1UDqbDcan 9sy1R+CB05AH1UAgOkY0 =E9Ep -----END PGP SIGNATURE----- Merge tag 'tilcdc-4.9-fixes' of https://github.com/jsarha/linux into drm-next tilcdc fixes for v4.9 * tag 'tilcdc-4.9-fixes' of https://github.com/jsarha/linux: drm/tilcdc: Choose console BPP that supports RGB drm/tilcdc: Add blue-and-red-crossed devicetree property drm/tilcdc: Write DMA base and ceiling address with single instruction drm/tilcdc: Remove drm_helper_disable_unused_functions() call drm/tilcdc: Enable EOF interrupts for v1 LCDC drm/tilcdc: Adjust the FB_CEILING address drm/tilcdc: Fix check for remote port parent
This commit is contained in:
commit
eb97027f07
|
@ -17,6 +17,18 @@ Optional properties:
|
|||
the lcd controller.
|
||||
- max-pixelclock: The maximum pixel clock that can be supported
|
||||
by the lcd controller in KHz.
|
||||
- blue-and-red-wiring: Recognized values "default", "straight" or
|
||||
"crossed". This property deals with the LCDC revision 2 (found on
|
||||
AM335x) color errata [1].
|
||||
- "straight" indicates normal wiring that supports RGB565,
|
||||
BGR888, and XBGR8888 color formats.
|
||||
- "crossed" indicates wiring that has blue and red wires
|
||||
crossed. This setup supports BGR565, RGB888 and XRGB8888
|
||||
formats.
|
||||
- If the property is not present or its value is not recognized
|
||||
the legacy mode is assumed. This configuration supports RGB565,
|
||||
RGB888 and XRGB8888 formats. However, depending on wiring, the red
|
||||
and blue colors are swapped in either 16 or 24-bit color modes.
|
||||
|
||||
Optional nodes:
|
||||
|
||||
|
@ -28,6 +40,14 @@ Optional nodes:
|
|||
Documentation/devicetree/bindings/display/tilcdc/tfp410.txt for connecting
|
||||
tfp410 DVI encoder or lcd panel to lcdc
|
||||
|
||||
[1] There is an errata about AM335x color wiring. For 16-bit color mode
|
||||
the wires work as they should (LCD_DATA[0:4] is for Blue[3:7]),
|
||||
but for 24 bit color modes the wiring of blue and red components is
|
||||
crossed and LCD_DATA[0:4] is for Red[3:7] and LCD_DATA[11:15] is
|
||||
for Blue[3-7]. For more details see section 3.1.1 in AM335x
|
||||
Silicon Errata:
|
||||
http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=sprz360
|
||||
|
||||
Example:
|
||||
|
||||
fb: fb@4830e000 {
|
||||
|
@ -37,6 +57,8 @@ Example:
|
|||
interrupts = <36>;
|
||||
ti,hwmods = "lcdc";
|
||||
|
||||
blue-and-red-wiring = "crossed";
|
||||
|
||||
port {
|
||||
lcdc_0: endpoint@0 {
|
||||
remote-endpoint = <&hdmi_0>;
|
||||
|
|
|
@ -69,6 +69,7 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
|
|||
struct drm_gem_cma_object *gem;
|
||||
unsigned int depth, bpp;
|
||||
dma_addr_t start, end;
|
||||
u64 dma_base_and_ceiling;
|
||||
|
||||
drm_fb_get_bpp_depth(fb->pixel_format, &depth, &bpp);
|
||||
gem = drm_fb_cma_get_gem_obj(fb, 0);
|
||||
|
@ -79,8 +80,13 @@ static void set_scanout(struct drm_crtc *crtc, struct drm_framebuffer *fb)
|
|||
|
||||
end = start + (crtc->mode.vdisplay * fb->pitches[0]);
|
||||
|
||||
tilcdc_write(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, start);
|
||||
tilcdc_write(dev, LCDC_DMA_FB_CEILING_ADDR_0_REG, end);
|
||||
/* Write LCDC_DMA_FB_BASE_ADDR_0_REG and LCDC_DMA_FB_CEILING_ADDR_0_REG
|
||||
* with a single insruction, if available. This should make it more
|
||||
* unlikely that LCDC would fetch the DMA addresses in the middle of
|
||||
* an update.
|
||||
*/
|
||||
dma_base_and_ceiling = (u64)(end - 1) << 32 | start;
|
||||
tilcdc_write64(dev, LCDC_DMA_FB_BASE_ADDR_0_REG, dma_base_and_ceiling);
|
||||
|
||||
if (tilcdc_crtc->curr_fb)
|
||||
drm_flip_work_queue(&tilcdc_crtc->unref_work,
|
||||
|
@ -98,6 +104,8 @@ static void tilcdc_crtc_enable_irqs(struct drm_device *dev)
|
|||
if (priv->rev == 1) {
|
||||
tilcdc_set(dev, LCDC_RASTER_CTRL_REG,
|
||||
LCDC_V1_UNDERFLOW_INT_ENA);
|
||||
tilcdc_set(dev, LCDC_DMA_CTRL_REG,
|
||||
LCDC_V1_END_OF_FRAME_INT_ENA);
|
||||
} else {
|
||||
tilcdc_write(dev, LCDC_INT_ENABLE_SET_REG,
|
||||
LCDC_V2_UNDERFLOW_INT_ENA |
|
||||
|
|
|
@ -33,6 +33,20 @@
|
|||
|
||||
static LIST_HEAD(module_list);
|
||||
|
||||
static const u32 tilcdc_rev1_formats[] = { DRM_FORMAT_RGB565 };
|
||||
|
||||
static const u32 tilcdc_straight_formats[] = { DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_BGR888,
|
||||
DRM_FORMAT_XBGR8888 };
|
||||
|
||||
static const u32 tilcdc_crossed_formats[] = { DRM_FORMAT_BGR565,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_XRGB8888 };
|
||||
|
||||
static const u32 tilcdc_legacy_formats[] = { DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_XRGB8888 };
|
||||
|
||||
void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
|
||||
const struct tilcdc_module_ops *funcs)
|
||||
{
|
||||
|
@ -226,7 +240,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
|
|||
struct platform_device *pdev = dev->platformdev;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct tilcdc_drm_private *priv;
|
||||
struct tilcdc_module *mod;
|
||||
struct resource *res;
|
||||
u32 bpp = 0;
|
||||
int ret;
|
||||
|
@ -318,6 +331,37 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
|
|||
|
||||
pm_runtime_put_sync(dev->dev);
|
||||
|
||||
if (priv->rev == 1) {
|
||||
DBG("Revision 1 LCDC supports only RGB565 format");
|
||||
priv->pixelformats = tilcdc_rev1_formats;
|
||||
priv->num_pixelformats = ARRAY_SIZE(tilcdc_rev1_formats);
|
||||
bpp = 16;
|
||||
} else {
|
||||
const char *str = "\0";
|
||||
|
||||
of_property_read_string(node, "blue-and-red-wiring", &str);
|
||||
if (0 == strcmp(str, "crossed")) {
|
||||
DBG("Configured for crossed blue and red wires");
|
||||
priv->pixelformats = tilcdc_crossed_formats;
|
||||
priv->num_pixelformats =
|
||||
ARRAY_SIZE(tilcdc_crossed_formats);
|
||||
bpp = 32; /* Choose bpp with RGB support for fbdef */
|
||||
} else if (0 == strcmp(str, "straight")) {
|
||||
DBG("Configured for straight blue and red wires");
|
||||
priv->pixelformats = tilcdc_straight_formats;
|
||||
priv->num_pixelformats =
|
||||
ARRAY_SIZE(tilcdc_straight_formats);
|
||||
bpp = 16; /* Choose bpp with RGB support for fbdef */
|
||||
} else {
|
||||
DBG("Blue and red wiring '%s' unknown, use legacy mode",
|
||||
str);
|
||||
priv->pixelformats = tilcdc_legacy_formats;
|
||||
priv->num_pixelformats =
|
||||
ARRAY_SIZE(tilcdc_legacy_formats);
|
||||
bpp = 16; /* This is just a guess */
|
||||
}
|
||||
}
|
||||
|
||||
ret = modeset_init(dev);
|
||||
if (ret < 0) {
|
||||
dev_err(dev->dev, "failed to initialize mode setting\n");
|
||||
|
@ -331,7 +375,7 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
|
|||
if (ret < 0)
|
||||
goto fail_mode_config_cleanup;
|
||||
|
||||
ret = tilcdc_add_external_encoders(dev, &bpp);
|
||||
ret = tilcdc_add_external_encoders(dev);
|
||||
if (ret < 0)
|
||||
goto fail_component_cleanup;
|
||||
}
|
||||
|
@ -354,15 +398,6 @@ static int tilcdc_load(struct drm_device *dev, unsigned long flags)
|
|||
goto fail_vblank_cleanup;
|
||||
}
|
||||
|
||||
list_for_each_entry(mod, &module_list, list) {
|
||||
DBG("%s: preferred_bpp: %d", mod->name, mod->preferred_bpp);
|
||||
bpp = mod->preferred_bpp;
|
||||
if (bpp > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
|
||||
drm_mode_config_reset(dev);
|
||||
|
||||
priv->fbdev = drm_fbdev_cma_init(dev, bpp,
|
||||
|
|
|
@ -65,6 +65,10 @@ struct tilcdc_drm_private {
|
|||
*/
|
||||
uint32_t max_width;
|
||||
|
||||
/* Supported pixel formats */
|
||||
const uint32_t *pixelformats;
|
||||
uint32_t num_pixelformats;
|
||||
|
||||
/* The context for pm susped/resume cycle is stored here */
|
||||
struct drm_atomic_state *saved_state;
|
||||
|
||||
|
@ -112,7 +116,6 @@ struct tilcdc_module {
|
|||
const char *name;
|
||||
struct list_head list;
|
||||
const struct tilcdc_module_ops *funcs;
|
||||
unsigned int preferred_bpp;
|
||||
};
|
||||
|
||||
void tilcdc_module_init(struct tilcdc_module *mod, const char *name,
|
||||
|
|
|
@ -52,7 +52,7 @@ static int tilcdc_external_mode_valid(struct drm_connector *connector,
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
|
||||
static int tilcdc_add_external_encoder(struct drm_device *dev,
|
||||
struct drm_connector *connector)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
|
@ -64,7 +64,6 @@ static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
|
|||
/* Only tda998x is supported at the moment. */
|
||||
tilcdc_crtc_set_simulate_vesa_sync(priv->crtc, true);
|
||||
tilcdc_crtc_set_panel_info(priv->crtc, &panel_info_tda998x);
|
||||
*bpp = panel_info_tda998x.bpp;
|
||||
|
||||
connector_funcs = devm_kzalloc(dev->dev, sizeof(*connector_funcs),
|
||||
GFP_KERNEL);
|
||||
|
@ -94,7 +93,7 @@ static int tilcdc_add_external_encoder(struct drm_device *dev, int *bpp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp)
|
||||
int tilcdc_add_external_encoders(struct drm_device *dev)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
struct drm_connector *connector;
|
||||
|
@ -108,7 +107,7 @@ int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp)
|
|||
if (connector == priv->connectors[i])
|
||||
found = true;
|
||||
if (!found) {
|
||||
ret = tilcdc_add_external_encoder(dev, bpp, connector);
|
||||
ret = tilcdc_add_external_encoder(dev, connector);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -154,7 +153,7 @@ int tilcdc_get_external_components(struct device *dev,
|
|||
|
||||
while ((ep = of_graph_get_next_endpoint(dev->of_node, ep))) {
|
||||
node = of_graph_get_remote_port_parent(ep);
|
||||
if (!node && !of_device_is_available(node)) {
|
||||
if (!node || !of_device_is_available(node)) {
|
||||
of_node_put(node);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#ifndef __TILCDC_EXTERNAL_H__
|
||||
#define __TILCDC_EXTERNAL_H__
|
||||
|
||||
int tilcdc_add_external_encoders(struct drm_device *dev, int *bpp);
|
||||
int tilcdc_add_external_encoders(struct drm_device *dev);
|
||||
void tilcdc_remove_external_encoders(struct drm_device *dev);
|
||||
int tilcdc_get_external_components(struct device *dev,
|
||||
struct component_match **match);
|
||||
|
|
|
@ -397,8 +397,6 @@ static int panel_probe(struct platform_device *pdev)
|
|||
goto fail_timings;
|
||||
}
|
||||
|
||||
mod->preferred_bpp = panel_mod->info->bpp;
|
||||
|
||||
return 0;
|
||||
|
||||
fail_timings:
|
||||
|
|
|
@ -24,10 +24,6 @@
|
|||
|
||||
#include "tilcdc_drv.h"
|
||||
|
||||
static const u32 tilcdc_formats[] = { DRM_FORMAT_RGB565,
|
||||
DRM_FORMAT_RGB888,
|
||||
DRM_FORMAT_XRGB8888 };
|
||||
|
||||
static struct drm_plane_funcs tilcdc_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
|
@ -114,12 +110,13 @@ static const struct drm_plane_helper_funcs plane_helper_funcs = {
|
|||
int tilcdc_plane_init(struct drm_device *dev,
|
||||
struct drm_plane *plane)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
int ret;
|
||||
|
||||
ret = drm_plane_init(dev, plane, 1,
|
||||
&tilcdc_plane_funcs,
|
||||
tilcdc_formats,
|
||||
ARRAY_SIZE(tilcdc_formats),
|
||||
priv->pixelformats,
|
||||
priv->num_pixelformats,
|
||||
true);
|
||||
if (ret) {
|
||||
dev_err(dev->dev, "Failed to initialize plane: %d\n", ret);
|
||||
|
|
|
@ -119,6 +119,20 @@ static inline void tilcdc_write(struct drm_device *dev, u32 reg, u32 data)
|
|||
iowrite32(data, priv->mmio + reg);
|
||||
}
|
||||
|
||||
static inline void tilcdc_write64(struct drm_device *dev, u32 reg, u64 data)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
volatile void __iomem *addr = priv->mmio + reg;
|
||||
|
||||
#ifdef iowrite64
|
||||
iowrite64(data, addr);
|
||||
#else
|
||||
__iowmb();
|
||||
/* This compiles to strd (=64-bit write) on ARM7 */
|
||||
*(volatile u64 __force *)addr = __cpu_to_le64(data);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline u32 tilcdc_read(struct drm_device *dev, u32 reg)
|
||||
{
|
||||
struct tilcdc_drm_private *priv = dev->dev_private;
|
||||
|
|
|
@ -327,8 +327,6 @@ static int tfp410_probe(struct platform_device *pdev)
|
|||
goto fail;
|
||||
}
|
||||
|
||||
mod->preferred_bpp = dvi_info.bpp;
|
||||
|
||||
i2c_node = of_find_node_by_phandle(i2c_phandle);
|
||||
if (!i2c_node) {
|
||||
dev_err(&pdev->dev, "could not get i2c bus node\n");
|
||||
|
|
Loading…
Reference in New Issue