#include <linux/component.h>
#include <linux/delay.h>
#include <linux/jiffies.h>
+#include <linux/media-bus-format.h>
#include <linux/mfd/syscon.h>
#include <linux/of_graph.h>
#include <linux/pinctrl/devinfo.h>
/* Bitfields in LVDSC_CFGR (Configuration Register) */
#define LVDSC_CFGR_PIXSIZE_24BITS 0
+#define LVDSC_CFGR_PIXSIZE_18BITS BIT(0)
#define LVDSC_CFGR_DEN_POL_HIGH 0
#define LVDSC_CFGR_DC_UNBALANCED 0
#define LVDSC_CFGR_MAPPING_JEIDA BIT(6)
+#define LVDSC_CFGR_MAPPING_VESA 0
/*Bitfields in LVDSC_SR */
#define LVDSC_SR_CS BIT(0)
writel_relaxed(val, lvds->regs + offset);
}
-static void lvds_serialiser_on(struct mchp_lvds *lvds)
+static void lvds_serialiser_on(struct mchp_lvds *lvds, u32 bus_format)
{
unsigned long timeout = jiffies + msecs_to_jiffies(LVDS_POLL_TIMEOUT_MS);
+ u8 map, pix_size;
/* The LVDSC registers can only be written if WPEN is cleared */
lvds_writel(lvds, LVDSC_WPMR, (LVDSC_WPMR_WPKEY_PSSWD &
usleep_range(1000, 2000);
}
+ switch (bus_format) {
+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
+ map = LVDSC_CFGR_MAPPING_JEIDA;
+ pix_size = LVDSC_CFGR_PIXSIZE_18BITS;
+ break;
+ case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
+ map = LVDSC_CFGR_MAPPING_VESA;
+ pix_size = LVDSC_CFGR_PIXSIZE_24BITS;
+ break;
+ default:
+ map = LVDSC_CFGR_MAPPING_JEIDA;
+ pix_size = LVDSC_CFGR_PIXSIZE_24BITS;
+ break;
+ }
+
/* Configure the LVDSC */
- lvds_writel(lvds, LVDSC_CFGR, (LVDSC_CFGR_MAPPING_JEIDA |
- LVDSC_CFGR_DC_UNBALANCED |
- LVDSC_CFGR_DEN_POL_HIGH |
- LVDSC_CFGR_PIXSIZE_24BITS));
+ lvds_writel(lvds, LVDSC_CFGR, map | LVDSC_CFGR_DC_UNBALANCED |
+ LVDSC_CFGR_DEN_POL_HIGH | pix_size);
/* Enable the LVDS serializer */
lvds_writel(lvds, LVDSC_CR, LVDSC_CR_SER_EN);
struct drm_atomic_state *state)
{
struct mchp_lvds *lvds = bridge_to_lvds(bridge);
+ struct drm_connector *connector;
int ret;
ret = clk_prepare_enable(lvds->pclk);
return;
}
- lvds_serialiser_on(lvds);
+ /* default to jeida-24 */
+ u32 bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA;
+
+ connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder);
+ if (connector && connector->display_info.num_bus_formats)
+ bus_format = connector->display_info.bus_formats[0];
+
+ lvds_serialiser_on(lvds, bus_format);
}
static void mchp_lvds_atomic_disable(struct drm_bridge *bridge,