Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
4f3ce1c
soundwire: cadence: merge routines to clear/set bits
plbossart Jan 17, 2020
363123a
soundwire: cadence: s/update_config/config_update
plbossart Jan 17, 2020
d59c129
soundwire: cadence: handle error cases with CONFIG_UPDATE
plbossart Jan 17, 2020
56c70f0
soundwire: cadence: move clock/SSP related inits to dedicated function
plbossart Jan 17, 2020
d172da1
soundwire: cadence: make SSP interval programmable
plbossart Feb 11, 2020
9b36491
soundwire: cadence: reorder MCP_CONFIG settings
plbossart Jan 17, 2020
10684f4
soundwire: cadence: enable NORMAL operation in cdns_init()
plbossart Jan 17, 2020
90f693e
soundwire: cadence: remove PREQ_DELAY assignment
plbossart Jan 23, 2020
3ccf47f
soundwire: cadence: remove automatic command retries
plbossart Jan 23, 2020
d195f90
soundwire: cadence: remove reset support from clock_restart
plbossart Feb 14, 2020
ad8a7e7
soundwire: cadence: commit changes in the exit_reset() sequence
plbossart Jan 17, 2020
59bad4f
soundwire: cadence: multi-link support
plbossart Feb 11, 2020
253b5a6
soundwire: intel: ignore software command retries
plbossart Jan 23, 2020
bd8d0a1
soundwire: intel: reuse code for wait loops to set/clear bits
plbossart Jan 17, 2020
8f50029
soundwire: intel: add definitions for shim_mask
plbossart Feb 6, 2020
b243edd
soundwire: intel: follow the recommended hardware flow to set SHIM_SYNC
plbossart Jan 16, 2020
1241b8e
soundwire: intel: introduce a helper to arm link synchronization
plbossart Jan 17, 2020
7dad127
soundwire: intel: introduce helper for link synchronization
plbossart Jan 17, 2020
226a5ab
soundwire: intel: add multi-link support
plbossart Jan 17, 2020
2a3b54f
soundwire: intel: add missing support for all clock stop modes
plbossart Feb 14, 2020
511335f
soundwire: bus: update multi-link definition with hw sync details
plbossart Jan 23, 2020
e2dee59
soundwire: intel: add multi-link hw_synchronization information
plbossart Jan 24, 2020
927586d
soundwire: stream: enable hw_sync as needed by hardware
plbossart Jan 24, 2020
38a10aa
soundwire: intel: add dynamic debug trace for clock-stop invalid configs
plbossart Feb 7, 2020
cbf6fea
[WORKAROUND] soundwire: intel: disable pm_runtime before unregisterin…
plbossart Feb 7, 2020
65c0f7f
soundwire: intel: pass link_mask information to each master
plbossart Feb 13, 2020
3144357
soundwire: intel: don't manage link power individually
plbossart Feb 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 68 additions & 63 deletions drivers/soundwire/cadence_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ MODULE_PARM_DESC(cdns_mcp_int_mask, "Cadence MCP IntMask");
#define CDNS_PDI_CONFIG_PORT GENMASK(4, 0)

/* Driver defaults */
#define CDNS_DEFAULT_SSP_INTERVAL 0x18
#define CDNS_TX_TIMEOUT 2000

#define CDNS_SCP_RX_FIFOLEVEL 0x2
Expand Down Expand Up @@ -212,26 +211,6 @@ static inline void cdns_updatel(struct sdw_cdns *cdns,
cdns_writel(cdns, offset, tmp);
}

static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
{
int timeout = 10;
u32 reg_read;

writel(value, cdns->registers + offset);

/* Wait for bit to be self cleared */
do {
reg_read = readl(cdns->registers + offset);
if ((reg_read & value) == 0)
return 0;

timeout--;
usleep_range(50, 100);
} while (timeout != 0);

return -EAGAIN;
}

static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
{
int timeout = 10;
Expand All @@ -250,14 +229,27 @@ static int cdns_set_wait(struct sdw_cdns *cdns, int offset, u32 mask, u32 value)
return -ETIMEDOUT;
}

static int cdns_clear_bit(struct sdw_cdns *cdns, int offset, u32 value)
{
writel(value, cdns->registers + offset);

/* Wait for bit to be self cleared */
return cdns_set_wait(cdns, offset, value, 0);
}

/*
* all changes to the MCP_CONFIG, MCP_CONTROL, MCP_CMDCTRL and MCP_PHYCTRL
* need to be confirmed with a write to MCP_CONFIG_UPDATE
*/
static int cdns_update_config(struct sdw_cdns *cdns)
static int cdns_config_update(struct sdw_cdns *cdns)
{
int ret;

if (sdw_cdns_is_clock_stop(cdns)) {
dev_err(cdns->dev, "Cannot program MCP_CONFIG_UPDATE in ClockStopMode\n");
return -EINVAL;
}

ret = cdns_clear_bit(cdns, CDNS_MCP_CONFIG_UPDATE,
CDNS_MCP_CONFIG_UPDATE_BIT);
if (ret < 0)
Expand Down Expand Up @@ -851,13 +843,14 @@ int sdw_cdns_exit_reset(struct sdw_cdns *cdns)
CDNS_MCP_CONTROL_HW_RST,
CDNS_MCP_CONTROL_HW_RST);

/* enable bus operations with clock and data */
cdns_updatel(cdns, CDNS_MCP_CONFIG,
CDNS_MCP_CONFIG_OP,
CDNS_MCP_CONFIG_OP_NORMAL);

/* commit changes */
return cdns_update_config(cdns);
cdns_updatel(cdns, CDNS_MCP_CONFIG_UPDATE,
CDNS_MCP_CONFIG_UPDATE_BIT,
CDNS_MCP_CONFIG_UPDATE_BIT);

/* don't wait here */
return 0;

}
EXPORT_SYMBOL(sdw_cdns_exit_reset);

Expand Down Expand Up @@ -1051,15 +1044,12 @@ static u32 cdns_set_initial_frame_shape(int n_rows, int n_cols)
return val;
}

/**
* sdw_cdns_init() - Cadence initialization
* @cdns: Cadence instance
*/
int sdw_cdns_init(struct sdw_cdns *cdns)
static void cdns_init_clock_ctrl(struct sdw_cdns *cdns)
{
struct sdw_bus *bus = &cdns->bus;
struct sdw_master_prop *prop = &bus->prop;
u32 val;
u32 ssp_interval;
int divider;

/* Set clock divider */
Expand All @@ -1079,8 +1069,20 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
cdns_writel(cdns, CDNS_MCP_FRAME_SHAPE_INIT, val);

/* Set SSP interval to default value */
cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, CDNS_DEFAULT_SSP_INTERVAL);
cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, CDNS_DEFAULT_SSP_INTERVAL);
ssp_interval = prop->default_frame_rate / SDW_CADENCE_GSYNC_HZ;
cdns_writel(cdns, CDNS_MCP_SSP_CTRL0, ssp_interval);
cdns_writel(cdns, CDNS_MCP_SSP_CTRL1, ssp_interval);
}

/**
* sdw_cdns_init() - Cadence initialization
* @cdns: Cadence instance
*/
int sdw_cdns_init(struct sdw_cdns *cdns)
{
u32 val;

cdns_init_clock_ctrl(cdns);

/* reset msg_count to default value of FIFOLEVEL */
cdns->msg_count = cdns_readl(cdns, CDNS_MCP_FIFOLEVEL);
Expand All @@ -1096,25 +1098,31 @@ int sdw_cdns_init(struct sdw_cdns *cdns)
/* Configure mcp config */
val = cdns_readl(cdns, CDNS_MCP_CONFIG);

/* Set Max cmd retry to 15 */
val |= CDNS_MCP_CONFIG_MCMD_RETRY;
/* enable bus operations with clock and data */
val &= ~CDNS_MCP_CONFIG_OP;
val |= CDNS_MCP_CONFIG_OP_NORMAL;

/* Set frame delay between PREQ and ping frame to 15 frames */
val |= 0xF << SDW_REG_SHIFT(CDNS_MCP_CONFIG_MPREQ_DELAY);
/* Set cmd mode for Tx and Rx cmds */
val &= ~CDNS_MCP_CONFIG_CMD;

/* Disable sniffer mode */
val &= ~CDNS_MCP_CONFIG_SNIFFER;

/* Disable auto bus release */
val &= ~CDNS_MCP_CONFIG_BUS_REL;

/* Disable sniffer mode */
val &= ~CDNS_MCP_CONFIG_SNIFFER;
if (cdns->bus.multi_link)
/* Set Multi-master mode to take gsync into account */
val |= CDNS_MCP_CONFIG_MMASTER;

/* Set cmd mode for Tx and Rx cmds */
val &= ~CDNS_MCP_CONFIG_CMD;
/* leave frame delay to hardware default of 0x1F */

/* leave command retry to hardware default of 0 */

cdns_writel(cdns, CDNS_MCP_CONFIG, val);

/* commit changes */
return cdns_update_config(cdns);
/* changes will be committed later */
return 0;
}
EXPORT_SYMBOL(sdw_cdns_init);

Expand Down Expand Up @@ -1326,7 +1334,11 @@ int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake)
CDNS_MCP_CONTROL_CMD_ACCEPT, 0);

/* commit changes */
cdns_update_config(cdns);
ret = cdns_config_update(cdns);
if (ret < 0) {
dev_err(cdns->dev, "%s: config_update failed\n", __func__);
return ret;
}

/* Prepare slaves for clock stop */
ret = sdw_bus_prep_clk_stop(&cdns->bus);
Expand Down Expand Up @@ -1391,26 +1403,19 @@ int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset)
*/
cdns_updatel(cdns, CDNS_MCP_CONTROL, CDNS_MCP_CONTROL_CMD_ACCEPT, 0);

if (bus_reset) {
/* program maximum length reset to be safe */
cdns_updatel(cdns, CDNS_MCP_CONTROL,
CDNS_MCP_CONTROL_RST_DELAY,
CDNS_MCP_CONTROL_RST_DELAY);
if (!bus_reset) {

/* use hardware generated reset */
cdns_updatel(cdns, CDNS_MCP_CONTROL,
CDNS_MCP_CONTROL_HW_RST,
CDNS_MCP_CONTROL_HW_RST);
}
/* enable bus operations with clock and data */
cdns_updatel(cdns, CDNS_MCP_CONFIG,
CDNS_MCP_CONFIG_OP,
CDNS_MCP_CONFIG_OP_NORMAL);

/* enable bus operations with clock and data */
cdns_updatel(cdns, CDNS_MCP_CONFIG,
CDNS_MCP_CONFIG_OP,
CDNS_MCP_CONFIG_OP_NORMAL);

cdns_update_config(cdns);
ret = cdns_config_update(cdns);
if (ret < 0) {
dev_err(cdns->dev, "%s: config_update failed\n", __func__);
return ret;
}

if (!bus_reset) {
ret = sdw_bus_exit_clk_stop(&cdns->bus);
if (ret < 0)
dev_err(cdns->dev, "bus failed to exit clock stop %d\n", ret);
Expand Down
3 changes: 3 additions & 0 deletions drivers/soundwire/cadence_master.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifndef __SDW_CADENCE_H
#define __SDW_CADENCE_H

#define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */
#define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000)

/**
* struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
*
Expand Down
Loading