[PATCH V2 11/11] drm/bridge: tc358767: Add DSI-to-DPI mode support

Marek Vasut marex at denx.de
Sat Feb 19 04:44:38 UTC 2022


On 2/18/22 19:38, Lucas Stach wrote:

[...]

>> @@ -502,8 +548,10 @@ static int tc_pxl_pll_en(struct tc_data *tc, u32 refclk, u32 pixelclock)
>>   				/*
>>   				 * refclk * mul / (ext_pre_div * pre_div)
>>   				 * should be in the 150 to 650 MHz range
>> +				 * for (e)DP
>>   				 */
>> -				if ((clk > 650000000) || (clk < 150000000))
>> +				if ((tc->bridge.type != DRM_MODE_CONNECTOR_DPI) &&
>> +				    ((clk > 650000000) || (clk < 150000000)))
>>   					continue;
> 
> Is there any indication what the bounds are for DPI mode? Can we
> replace this with a better check, instead of just disabling it?

Apparently the DPI pixel PLL output is limited to 100 MHz, so yes, this 
can be improved.

[...]

>> +static int tc_dpi_stream_enable(struct tc_data *tc)
>> +{
>> +	int ret;
>> +	u32 value;
>> +
>> +	dev_dbg(tc->dev, "enable video stream\n");
>> +
>> +	/* Setup PLL */
>> +	ret = tc_set_syspllparam(tc);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Pixel PLL must always be enabled for DPI mode */
>> +	ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk),
>> +			    1000 * tc->mode.clock);
>> +	if (ret)
>> +		return ret;
>> +
>> +	regmap_write(tc->regmap, PPI_D0S_CLRSIPOCOUNT, 3);
>> +	regmap_write(tc->regmap, PPI_D1S_CLRSIPOCOUNT, 3);
>> +	regmap_write(tc->regmap, PPI_D2S_CLRSIPOCOUNT, 3);
>> +	regmap_write(tc->regmap, PPI_D3S_CLRSIPOCOUNT, 3);
> 
> Hm, those hardcoded always seem kind of fishy, as AFAIK those
> parameters are dependent on land frequency and some other things. But
> I'm also not sure if we have all the information available to
> dynamically calculate them.

We have multiple copies of the same ^ code in other TC358nnn drivers 
too, it seems like some de-duplication could be done too. I have this 
feeling the Toshiba bridges are all glued together from two (or more) 
halves and there is large potential for de-duplication in all those TC 
drivers. But does anyone really have all the chips to test, except for 
Toshiba ?

>> +	regmap_write(tc->regmap, PPI_D0S_ATMR, 0);
>> +	regmap_write(tc->regmap, PPI_D1S_ATMR, 0);
>> +	regmap_write(tc->regmap, PPI_TX_RX_TA, TTA_GET | TTA_SURE);
>> +	regmap_write(tc->regmap, PPI_LPTXTIMECNT, LPX_PERIOD);
>> +
>> +	value = ((LANEENABLE_L0EN << tc->dsi_lanes) - LANEENABLE_L0EN) |
>> +		LANEENABLE_CLEN;
>> +	regmap_write(tc->regmap, PPI_LANEENABLE, value);
>> +	regmap_write(tc->regmap, DSI_LANEENABLE, value);
>> +
>> +	ret = tc_set_common_video_mode(tc, &tc->mode);
>> +	if (ret)
>> +		return ret;
>> +
>> +	ret = tc_set_dpi_video_mode(tc, &tc->mode);
>> +	if (ret)
>> +		return ret;
>> +
>> +	/* Set input interface */
>> +	value = DP0_AUDSRC_NO_INPUT;
>> +	if (tc_test_pattern)
>> +		value |= DP0_VIDSRC_COLOR_BAR;
>> +	else
>> +		value |= DP0_VIDSRC_DSI_RX;
>> +	ret = regmap_write(tc->regmap, SYSCTRL, value);
>> +	if (ret)
>> +		return ret;
>> +
>> +	msleep(100);
> 
> What is that used for? PLL stabilization? Some other purpose?

Yes, except that should've been microseconds ... fixed

[...]

>> +static int tc_mipi_dsi_host_attach(struct tc_data *tc)
>> +{
>> +	struct device *dev = tc->dev;
>> +	struct device_node *host_node;
>> +	struct device_node *endpoint;
>> +	struct mipi_dsi_device *dsi;
>> +	struct mipi_dsi_host *host;
>> +	const struct mipi_dsi_device_info info = {
>> +		.type = "tc358767",
>> +		.channel = 0,
>> +		.node = NULL,
>> +	};
>> +	int ret;
>> +
>> +	endpoint = of_graph_get_endpoint_by_regs(dev->of_node, 0, 0);
>> +	tc->dsi_lanes = of_property_count_u32_elems(endpoint, "data-lanes");
> 
> The data-lanes property isn't documented in the DT binding. Please add.

Fixed in a separate patch.

[...]

>> @@ -1828,15 +2145,23 @@ static int tc_probe(struct i2c_client *client, const struct i2c_device_id *id)
>>   		tc->have_irq = true;
>>   	}
>>   
>> -	ret = tc_aux_link_setup(tc);
>> -	if (ret)
>> -		return ret;
>> +	if (tc->bridge.type != DRM_MODE_CONNECTOR_DPI) { /* (e)DP output */
>> +		ret = tc_aux_link_setup(tc);
>> +		if (ret)
>> +			return ret;
>> +	}
>>   
>>   	tc->bridge.of_node = dev->of_node;
>>   	drm_bridge_add(&tc->bridge);
>>   
>>   	i2c_set_clientdata(client, tc);
>>   
>> +	if (tc->bridge.type == DRM_MODE_CONNECTOR_DPI) { /* DPI output */
>> +		ret = tc_mipi_dsi_host_attach(tc);
>> +		if (ret)
>> +			return ret;
>> +	}
> 
> If tc_mipi_dsi_host_attach fails the drm bridge registered a few lines
> above isn't cleaned up properly.

Fixed


More information about the dri-devel mailing list