mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-04-21 04:53:46 -04:00
drm/msm/dp: move all IO handling to dp_catalog
Rather than parsing the I/O addresses from dp_parser and then passing them via a struct pointer to dp_catalog, handle I/O region parsing in dp_catalog and drop it from dp_parser. Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Tested-by: Kuogee Hsieh <quic_khsieh@quicinc.com> Reviewed-by: Kuogee Hsieh <quic_khsieh@quicinc.com> Patchwork: https://patchwork.freedesktop.org/patch/576108/ Link: https://lore.kernel.org/r/20240126-dp-power-parser-cleanup-v3-12-098d5f581dd3@linaro.org
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/rational.h>
|
||||
#include <drm/display/drm_dp_helper.h>
|
||||
#include <drm/drm_print.h>
|
||||
@@ -53,10 +54,31 @@
|
||||
(PSR_UPDATE_MASK | PSR_CAPTURE_MASK | PSR_EXIT_MASK | \
|
||||
PSR_UPDATE_ERROR_MASK | PSR_WAKE_ERROR_MASK)
|
||||
|
||||
#define DP_DEFAULT_AHB_OFFSET 0x0000
|
||||
#define DP_DEFAULT_AHB_SIZE 0x0200
|
||||
#define DP_DEFAULT_AUX_OFFSET 0x0200
|
||||
#define DP_DEFAULT_AUX_SIZE 0x0200
|
||||
#define DP_DEFAULT_LINK_OFFSET 0x0400
|
||||
#define DP_DEFAULT_LINK_SIZE 0x0C00
|
||||
#define DP_DEFAULT_P0_OFFSET 0x1000
|
||||
#define DP_DEFAULT_P0_SIZE 0x0400
|
||||
|
||||
struct dss_io_region {
|
||||
size_t len;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
struct dss_io_data {
|
||||
struct dss_io_region ahb;
|
||||
struct dss_io_region aux;
|
||||
struct dss_io_region link;
|
||||
struct dss_io_region p0;
|
||||
};
|
||||
|
||||
struct dp_catalog_private {
|
||||
struct device *dev;
|
||||
struct drm_device *drm_dev;
|
||||
struct dp_io *io;
|
||||
struct dss_io_data io;
|
||||
u32 (*audio_map)[DP_AUDIO_SDP_HEADER_MAX];
|
||||
struct dp_catalog dp_catalog;
|
||||
u8 aux_lut_cfg_index[PHY_AUX_CFG_MAX];
|
||||
@@ -66,7 +88,7 @@ void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *d
|
||||
{
|
||||
struct dp_catalog_private *catalog = container_of(dp_catalog,
|
||||
struct dp_catalog_private, dp_catalog);
|
||||
struct dss_io_data *dss = &catalog->io->dp_controller;
|
||||
struct dss_io_data *dss = &catalog->io;
|
||||
|
||||
msm_disp_snapshot_add_block(disp_state, dss->ahb.len, dss->ahb.base, "dp_ahb");
|
||||
msm_disp_snapshot_add_block(disp_state, dss->aux.len, dss->aux.base, "dp_aux");
|
||||
@@ -76,7 +98,7 @@ void dp_catalog_snapshot(struct dp_catalog *dp_catalog, struct msm_disp_state *d
|
||||
|
||||
static inline u32 dp_read_aux(struct dp_catalog_private *catalog, u32 offset)
|
||||
{
|
||||
return readl_relaxed(catalog->io->dp_controller.aux.base + offset);
|
||||
return readl_relaxed(catalog->io.aux.base + offset);
|
||||
}
|
||||
|
||||
static inline void dp_write_aux(struct dp_catalog_private *catalog,
|
||||
@@ -86,12 +108,12 @@ static inline void dp_write_aux(struct dp_catalog_private *catalog,
|
||||
* To make sure aux reg writes happens before any other operation,
|
||||
* this function uses writel() instread of writel_relaxed()
|
||||
*/
|
||||
writel(data, catalog->io->dp_controller.aux.base + offset);
|
||||
writel(data, catalog->io.aux.base + offset);
|
||||
}
|
||||
|
||||
static inline u32 dp_read_ahb(const struct dp_catalog_private *catalog, u32 offset)
|
||||
{
|
||||
return readl_relaxed(catalog->io->dp_controller.ahb.base + offset);
|
||||
return readl_relaxed(catalog->io.ahb.base + offset);
|
||||
}
|
||||
|
||||
static inline void dp_write_ahb(struct dp_catalog_private *catalog,
|
||||
@@ -101,7 +123,7 @@ static inline void dp_write_ahb(struct dp_catalog_private *catalog,
|
||||
* To make sure phy reg writes happens before any other operation,
|
||||
* this function uses writel() instread of writel_relaxed()
|
||||
*/
|
||||
writel(data, catalog->io->dp_controller.ahb.base + offset);
|
||||
writel(data, catalog->io.ahb.base + offset);
|
||||
}
|
||||
|
||||
static inline void dp_write_p0(struct dp_catalog_private *catalog,
|
||||
@@ -111,7 +133,7 @@ static inline void dp_write_p0(struct dp_catalog_private *catalog,
|
||||
* To make sure interface reg writes happens before any other operation,
|
||||
* this function uses writel() instread of writel_relaxed()
|
||||
*/
|
||||
writel(data, catalog->io->dp_controller.p0.base + offset);
|
||||
writel(data, catalog->io.p0.base + offset);
|
||||
}
|
||||
|
||||
static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
|
||||
@@ -121,12 +143,12 @@ static inline u32 dp_read_p0(struct dp_catalog_private *catalog,
|
||||
* To make sure interface reg writes happens before any other operation,
|
||||
* this function uses writel() instread of writel_relaxed()
|
||||
*/
|
||||
return readl_relaxed(catalog->io->dp_controller.p0.base + offset);
|
||||
return readl_relaxed(catalog->io.p0.base + offset);
|
||||
}
|
||||
|
||||
static inline u32 dp_read_link(struct dp_catalog_private *catalog, u32 offset)
|
||||
{
|
||||
return readl_relaxed(catalog->io->dp_controller.link.base + offset);
|
||||
return readl_relaxed(catalog->io.link.base + offset);
|
||||
}
|
||||
|
||||
static inline void dp_write_link(struct dp_catalog_private *catalog,
|
||||
@@ -136,7 +158,7 @@ static inline void dp_write_link(struct dp_catalog_private *catalog,
|
||||
* To make sure link reg writes happens before any other operation,
|
||||
* this function uses writel() instread of writel_relaxed()
|
||||
*/
|
||||
writel(data, catalog->io->dp_controller.link.base + offset);
|
||||
writel(data, catalog->io.link.base + offset);
|
||||
}
|
||||
|
||||
/* aux related catalog functions */
|
||||
@@ -248,7 +270,7 @@ int dp_catalog_aux_wait_for_hpd_connect_state(struct dp_catalog *dp_catalog)
|
||||
struct dp_catalog_private, dp_catalog);
|
||||
|
||||
/* poll for hpd connected status every 2ms and timeout after 500ms */
|
||||
return readl_poll_timeout(catalog->io->dp_controller.aux.base +
|
||||
return readl_poll_timeout(catalog->io.aux.base +
|
||||
REG_DP_DP_HPD_INT_STATUS,
|
||||
state, state & DP_DP_HPD_STATE_STATUS_CONNECTED,
|
||||
2000, 500000);
|
||||
@@ -276,7 +298,7 @@ void dp_catalog_dump_regs(struct dp_catalog *dp_catalog)
|
||||
{
|
||||
struct dp_catalog_private *catalog = container_of(dp_catalog,
|
||||
struct dp_catalog_private, dp_catalog);
|
||||
struct dss_io_data *io = &catalog->io->dp_controller;
|
||||
struct dss_io_data *io = &catalog->io;
|
||||
|
||||
pr_info("AHB regs\n");
|
||||
dump_regs(io->ahb.base, io->ahb.len);
|
||||
@@ -500,7 +522,7 @@ int dp_catalog_ctrl_set_pattern_state_bit(struct dp_catalog *dp_catalog,
|
||||
bit = BIT(state_bit - 1) << DP_MAINLINK_READY_LINK_TRAINING_SHIFT;
|
||||
|
||||
/* Poll for mainlink ready status */
|
||||
ret = readx_poll_timeout(readl, catalog->io->dp_controller.link.base +
|
||||
ret = readx_poll_timeout(readl, catalog->io.link.base +
|
||||
REG_DP_MAINLINK_READY,
|
||||
data, data & bit,
|
||||
POLLING_SLEEP_US, POLLING_TIMEOUT_US);
|
||||
@@ -563,7 +585,7 @@ bool dp_catalog_ctrl_mainlink_ready(struct dp_catalog *dp_catalog)
|
||||
struct dp_catalog_private, dp_catalog);
|
||||
|
||||
/* Poll for mainlink ready status */
|
||||
ret = readl_poll_timeout(catalog->io->dp_controller.link.base +
|
||||
ret = readl_poll_timeout(catalog->io.link.base +
|
||||
REG_DP_MAINLINK_READY,
|
||||
data, data & DP_MAINLINK_READY_FOR_VIDEO,
|
||||
POLLING_SLEEP_US, POLLING_TIMEOUT_US);
|
||||
@@ -945,21 +967,84 @@ void dp_catalog_panel_tpg_disable(struct dp_catalog *dp_catalog)
|
||||
dp_write_p0(catalog, MMSS_DP_TIMING_ENGINE_EN, 0x0);
|
||||
}
|
||||
|
||||
struct dp_catalog *dp_catalog_get(struct device *dev, struct dp_io *io)
|
||||
static void __iomem *dp_ioremap(struct platform_device *pdev, int idx, size_t *len)
|
||||
{
|
||||
struct resource *res;
|
||||
void __iomem *base;
|
||||
|
||||
base = devm_platform_get_and_ioremap_resource(pdev, idx, &res);
|
||||
if (!IS_ERR(base))
|
||||
*len = resource_size(res);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static int dp_catalog_get_io(struct dp_catalog_private *catalog)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(catalog->dev);
|
||||
struct dss_io_data *dss = &catalog->io;
|
||||
|
||||
dss->ahb.base = dp_ioremap(pdev, 0, &dss->ahb.len);
|
||||
if (IS_ERR(dss->ahb.base))
|
||||
return PTR_ERR(dss->ahb.base);
|
||||
|
||||
dss->aux.base = dp_ioremap(pdev, 1, &dss->aux.len);
|
||||
if (IS_ERR(dss->aux.base)) {
|
||||
/*
|
||||
* The initial binding had a single reg, but in order to
|
||||
* support variation in the sub-region sizes this was split.
|
||||
* dp_ioremap() will fail with -EINVAL here if only a single
|
||||
* reg is specified, so fill in the sub-region offsets and
|
||||
* lengths based on this single region.
|
||||
*/
|
||||
if (PTR_ERR(dss->aux.base) == -EINVAL) {
|
||||
if (dss->ahb.len < DP_DEFAULT_P0_OFFSET + DP_DEFAULT_P0_SIZE) {
|
||||
DRM_ERROR("legacy memory region not large enough\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dss->ahb.len = DP_DEFAULT_AHB_SIZE;
|
||||
dss->aux.base = dss->ahb.base + DP_DEFAULT_AUX_OFFSET;
|
||||
dss->aux.len = DP_DEFAULT_AUX_SIZE;
|
||||
dss->link.base = dss->ahb.base + DP_DEFAULT_LINK_OFFSET;
|
||||
dss->link.len = DP_DEFAULT_LINK_SIZE;
|
||||
dss->p0.base = dss->ahb.base + DP_DEFAULT_P0_OFFSET;
|
||||
dss->p0.len = DP_DEFAULT_P0_SIZE;
|
||||
} else {
|
||||
DRM_ERROR("unable to remap aux region: %pe\n", dss->aux.base);
|
||||
return PTR_ERR(dss->aux.base);
|
||||
}
|
||||
} else {
|
||||
dss->link.base = dp_ioremap(pdev, 2, &dss->link.len);
|
||||
if (IS_ERR(dss->link.base)) {
|
||||
DRM_ERROR("unable to remap link region: %pe\n", dss->link.base);
|
||||
return PTR_ERR(dss->link.base);
|
||||
}
|
||||
|
||||
dss->p0.base = dp_ioremap(pdev, 3, &dss->p0.len);
|
||||
if (IS_ERR(dss->p0.base)) {
|
||||
DRM_ERROR("unable to remap p0 region: %pe\n", dss->p0.base);
|
||||
return PTR_ERR(dss->p0.base);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dp_catalog *dp_catalog_get(struct device *dev)
|
||||
{
|
||||
struct dp_catalog_private *catalog;
|
||||
|
||||
if (!io) {
|
||||
DRM_ERROR("invalid input\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
int ret;
|
||||
|
||||
catalog = devm_kzalloc(dev, sizeof(*catalog), GFP_KERNEL);
|
||||
if (!catalog)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
catalog->dev = dev;
|
||||
catalog->io = io;
|
||||
|
||||
ret = dp_catalog_get_io(catalog);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return &catalog->dp_catalog;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user