Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
77 changes: 10 additions & 67 deletions drivers/regulator/rpi-panel-attiny-regulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,24 +143,8 @@ static int attiny_lcd_power_disable(struct regulator_dev *rdev)
static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev)
{
struct attiny_lcd *state = rdev_get_drvdata(rdev);
unsigned int data;
int ret, i;

mutex_lock(&state->lock);

for (i = 0; i < 10; i++) {
ret = regmap_read(rdev->regmap, REG_PORTC, &data);
if (!ret)
break;
usleep_range(10000, 12000);
}

mutex_unlock(&state->lock);

if (ret < 0)
return ret;

return data & PC_RST_BRIDGE_N;
return state->port_states[REG_PORTC - REG_PORTA] & PC_RST_BRIDGE_N;
}

static const struct regulator_init_data attiny_regulator_default = {
Expand Down Expand Up @@ -245,39 +229,6 @@ static void attiny_gpio_set(struct gpio_chip *gc, unsigned int off, int val)
mutex_unlock(&state->lock);
}

static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf)
{
struct i2c_msg msgs[1];
u8 addr_buf[1] = { reg };
u8 data_buf[1] = { 0, };
int ret;

/* Write register address */
msgs[0].addr = client->addr;
msgs[0].flags = 0;
msgs[0].len = ARRAY_SIZE(addr_buf);
msgs[0].buf = addr_buf;

ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
return -EIO;

usleep_range(5000, 10000);

/* Read data from register */
msgs[0].addr = client->addr;
msgs[0].flags = I2C_M_RD;
msgs[0].len = 1;
msgs[0].buf = data_buf;

ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
return -EIO;

*buf = data_buf[0];
return 0;
}

/*
* I2C driver interface functions
*/
Expand All @@ -289,7 +240,6 @@ static int attiny_i2c_probe(struct i2c_client *i2c)
struct regulator_dev *rdev;
struct attiny_lcd *state;
struct regmap *regmap;
unsigned int data;
int ret;

state = devm_kzalloc(&i2c->dev, sizeof(*state), GFP_KERNEL);
Expand All @@ -307,22 +257,6 @@ static int attiny_i2c_probe(struct i2c_client *i2c)
goto error;
}

ret = attiny_i2c_read(i2c, REG_ID, &data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret);
goto error;
}

switch (data) {
case 0xde: /* ver 1 */
case 0xc3: /* ver 2 */
break;
default:
dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data);
ret = -ENODEV;
goto error;
}

regmap_write(regmap, REG_POWERON, 0);
msleep(30);
regmap_write(regmap, REG_PWM, 0);
Expand Down Expand Up @@ -386,6 +320,14 @@ static void attiny_i2c_remove(struct i2c_client *client)
mutex_destroy(&state->lock);
}

static void attiny_i2c_shutdown(struct i2c_client *client)
{
struct attiny_lcd *state = i2c_get_clientdata(client);

regmap_write(state->regmap, REG_PWM, 0);
regmap_write(state->regmap, REG_POWERON, 0);
}

static const struct of_device_id attiny_dt_ids[] = {
{ .compatible = "raspberrypi,7inch-touchscreen-panel-regulator" },
{},
Expand All @@ -400,6 +342,7 @@ static struct i2c_driver attiny_regulator_driver = {
},
.probe = attiny_i2c_probe,
.remove = attiny_i2c_remove,
.shutdown = attiny_i2c_shutdown,
};

module_i2c_driver(attiny_regulator_driver);
Expand Down
4 changes: 4 additions & 0 deletions drivers/video/fbdev/mxc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,7 @@ config FB_MXC_DCIC
depends on FB_MXC_SYNC_PANEL
depends on MXC_IPU_V3 || FB_MXS
select VIDEOMODE_HELPERS

config FB_MXC_RPI_7INCH_LCD
depends on I2C
tristate "Raspberry Pi 7 inch LCD"
1 change: 1 addition & 0 deletions drivers/video/fbdev/mxc/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
obj-$(CONFIG_FB_MXC_RPI_7INCH_LCD) += mxcfb_rpi_7inch.o
obj-$(CONFIG_FB_MXC_DISP_FRAMEWORK) += mxc_dispdrv.o
obj-$(CONFIG_FB_MXC_MIPI_DSI_NORTHWEST) += mipi_dsi_northwest.o
obj-$(CONFIG_FB_MXC_EDID) += mxc_edid.o
Expand Down
9 changes: 8 additions & 1 deletion drivers/video/fbdev/mxc/mipi_dsi.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ struct mipi_dsi_info {
int dsi_power_on;
int lcd_inited;
int encoder;
int traffic_mode;
u32 traffic_mode;
u32 non_continuous_clock;
u32 auto_eotp;
u32 dphy_pll_config;
int dev_id;
int disp_id;
Expand Down Expand Up @@ -187,5 +189,10 @@ void mipid_hx8394_get_lcd_videomode(struct fb_videomode **mode, int *size,
struct mipi_lcd_config **data);
int mipid_hx8394_lcd_setup(struct mipi_dsi_info *mipi_dsi);
#endif
#ifdef CONFIG_FB_MXC_RPI_7INCH_LCD
void mipid_rpi_get_lcd_videomode(struct fb_videomode **mode, int *size,
struct mipi_lcd_config **data);
int mipid_rpi_lcd_setup(struct mipi_dsi_info *mipi_dsi);
#endif

#endif
63 changes: 57 additions & 6 deletions drivers/video/fbdev/mxc/mipi_dsi_northwest.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
"ROCKTECH-RK055AHD091",
{mipid_hx8394_get_lcd_videomode, mipid_hx8394_lcd_setup}
},
#endif
#ifdef CONFIG_FB_MXC_RPI_7INCH_LCD
{
"RPI-7INCH-LCD",
{mipid_rpi_get_lcd_videomode, mipid_rpi_lcd_setup}
},
#endif
{
"", {NULL, NULL}
Expand Down Expand Up @@ -375,10 +381,12 @@ static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,

switch (mode) {
case DSI_LP_MODE:
writel(0x1, mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
writel(mipi_dsi->non_continuous_clock,
mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
break;
case DSI_HS_MODE:
writel(0x0, mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);

break;
default:
dev_err(&mipi_dsi->pdev->dev,
Expand Down Expand Up @@ -449,6 +457,8 @@ static int mipi_dsi_dphy_init(struct mipi_dsi_info *mipi_dsi)
"requested data lane num is invalid\n");
return -EINVAL;
}
dev_info(&mipi_dsi->pdev->dev, "DSI bit clock: %u bpp %u lanes %u\n",
req_bit_clk, bpp, lcd_config->data_lane_num);

if (mipi_dsi->encoder) {
if (req_bit_clk > lcd_config->max_phy_clk)
Expand Down Expand Up @@ -695,13 +705,13 @@ static int mipi_dsi_host_init(struct mipi_dsi_info *mipi_dsi)
#endif

writel(lane_num, mipi_dsi->mmio_base + HOST_CFG_NUM_LANES);
writel(mipi_dsi->encoder ? 0x0 : 0x1,
writel(mipi_dsi->non_continuous_clock,
mipi_dsi->mmio_base + HOST_CFG_NONCONTINUOUS_CLK);
writel(0x1, mipi_dsi->mmio_base + HOST_CFG_T_PRE);
writel(52, mipi_dsi->mmio_base + HOST_CFG_T_POST);
writel(13, mipi_dsi->mmio_base + HOST_CFG_TX_GAP);
writel(mipi_dsi->encoder ? 0x0 : 0x1,
mipi_dsi->mmio_base + HOST_CFG_AUTOINSERT_EOTP);
writel(mipi_dsi->auto_eotp,
mipi_dsi->mmio_base + HOST_CFG_AUTOINSERT_EOTP);
writel(0x0, mipi_dsi->mmio_base + HOST_CFG_EXTRA_CMDS_AFTER_EOTP);
writel(0x0, mipi_dsi->mmio_base + HOST_CFG_HTX_TO_COUNT);
writel(0x0, mipi_dsi->mmio_base + HOST_CFG_LRX_H_TO_COUNT);
Expand All @@ -717,8 +727,12 @@ static int mipi_dsi_dpi_init(struct mipi_dsi_info *mipi_dsi)
uint32_t pixel_fifo_level, hfp_period, hbp_period, hsa_period;
struct fb_videomode *mode = mipi_dsi->mode;
struct mipi_lcd_config *lcd_config = mipi_dsi->lcd_config;
uint32_t bytes_per_pixel;
uint32_t blank;
uint32_t pl, phl;

bpp = fmt_to_bpp(lcd_config->dpi_fmt);
bytes_per_pixel = bpp / 8;

writel(mode->xres, mipi_dsi->mmio_base + DPI_PIXEL_PAYLOAD_SIZE);

Expand All @@ -735,6 +749,28 @@ static int mipi_dsi_dpi_init(struct mipi_dsi_info *mipi_dsi)
hbp_period = 0x60;
hsa_period = 0xf0;
#endif

/* see drivers/gpu/drm/bridge/nwl-dsi.c */
pixel_fifo_level = mode->xres;
hfp_period = mode->right_margin * bytes_per_pixel;
hbp_period = mode->left_margin * bytes_per_pixel;
hsa_period = mode->hsync_len * bytes_per_pixel;
/* should be even ?*/
hfp_period = roundup(hfp_period, 2);
hbp_period = roundup(hbp_period, 2);
hsa_period = roundup(hsa_period, 2);

blank = hfp_period + hbp_period + hsa_period;
pl = roundup(((hfp_period * 100 / blank) * 32) / 100, 2);
phl = pl;
hfp_period -= pl;
pl = roundup(((hbp_period * 100 / blank) * 32) / 100, 2);
phl += pl;
hbp_period -= pl;

hsa_period -= (phl <= 32) ? 32 - phl : 0;
dev_dbg(&mipi_dsi->pdev->dev, " Actual hfp/hsa/hbp: %u/%u/%u",
hfp_period, hsa_period, hbp_period);
break;
case DSI_BURST_MODE:
pixel_fifo_level = mode->xres;
Expand Down Expand Up @@ -779,6 +815,8 @@ static int mipi_dsi_dpi_init(struct mipi_dsi_info *mipi_dsi)
writel(0x0, mipi_dsi->mmio_base + DPI_VSYNC_POLARITY);
writel(0x0, mipi_dsi->mmio_base + DPI_HSYNC_POLARITY);
#endif
dev_info(&mipi_dsi->pdev->dev, "%s: traffic_mode:%u\n",
__func__, mipi_dsi->traffic_mode);
writel(mipi_dsi->traffic_mode,
mipi_dsi->mmio_base + DPI_VIDEO_MODE);

Expand Down Expand Up @@ -1068,7 +1106,7 @@ static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
const uint8_t *data = (const uint8_t *)buf;

if (len == 0)
/* handle generic long write command */
/* handle generic short write command */
mipi_dsi_wr_tx_header(mipi_dsi, data_type, data[0], data[1], DSI_LP_MODE, 0);
else {
reinit_completion(&dsi_tx_done);
Expand Down Expand Up @@ -1388,6 +1426,12 @@ static int mipi_dsi_probe(struct platform_device *pdev)
return -EINVAL;
}
#endif
/* Properties names should be inverted, but to keep backward
* compatibility no property is treated as previously default value */
mipi_dsi->non_continuous_clock = !of_property_read_bool(np,
"continuous-clock");
mipi_dsi->auto_eotp = !of_property_read_bool(np, "no-auto-eotp");

/* check whether an encoder exists */
endpoint = of_graph_get_next_endpoint(np, NULL);
if (endpoint) {
Expand Down Expand Up @@ -1425,9 +1469,16 @@ static int mipi_dsi_probe(struct platform_device *pdev)
}

mipi_dsi->encoder = 1;
/* backward compatibility: this settings depended on encoder.
* set option values to match */
mipi_dsi->non_continuous_clock = 0;
mipi_dsi->auto_eotp = 0;
} else {
/* Default, using 'BURST-MODE' for mipi panel */
mipi_dsi->traffic_mode = 2;
ret = of_property_read_u32(np, "dsi-traffic-mode",
&mipi_dsi->traffic_mode);
if (ret < 0 || mipi_dsi->traffic_mode > 2)
mipi_dsi->traffic_mode = DSI_BURST_MODE;

ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
if (ret) {
Expand Down
Loading