diff options
Diffstat (limited to 'drivers/gpu/drm/panel/panel-simple.c')
| -rw-r--r-- | drivers/gpu/drm/panel/panel-simple.c | 225 | 
1 files changed, 164 insertions, 61 deletions
| diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c index 5d487686d25c..e14c14ac62b5 100644 --- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -21,7 +21,6 @@   * DEALINGS IN THE SOFTWARE.   */ -#include <linux/backlight.h>  #include <linux/delay.h>  #include <linux/gpio/consumer.h>  #include <linux/module.h> @@ -105,7 +104,6 @@ struct panel_simple {  	const struct panel_desc *desc; -	struct backlight_device *backlight;  	struct regulator *supply;  	struct i2c_adapter *ddc; @@ -119,10 +117,9 @@ static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)  	return container_of(panel, struct panel_simple, base);  } -static unsigned int panel_simple_get_timings_modes(struct panel_simple *panel) +static unsigned int panel_simple_get_timings_modes(struct panel_simple *panel, +						   struct drm_connector *connector)  { -	struct drm_connector *connector = panel->base.connector; -	struct drm_device *drm = panel->base.drm;  	struct drm_display_mode *mode;  	unsigned int i, num = 0; @@ -131,9 +128,9 @@ static unsigned int panel_simple_get_timings_modes(struct panel_simple *panel)  		struct videomode vm;  		videomode_from_timing(dt, &vm); -		mode = drm_mode_create(drm); +		mode = drm_mode_create(connector->dev);  		if (!mode) { -			dev_err(drm->dev, "failed to add mode %ux%u\n", +			dev_err(panel->base.dev, "failed to add mode %ux%u\n",  				dt->hactive.typ, dt->vactive.typ);  			continue;  		} @@ -152,19 +149,18 @@ static unsigned int panel_simple_get_timings_modes(struct panel_simple *panel)  	return num;  } -static unsigned int panel_simple_get_display_modes(struct panel_simple *panel) +static unsigned int panel_simple_get_display_modes(struct panel_simple *panel, +						   struct drm_connector *connector)  { -	struct drm_connector *connector = panel->base.connector; -	struct drm_device *drm = panel->base.drm;  	struct drm_display_mode *mode;  	unsigned int i, num = 0;  	for (i = 0; i < panel->desc->num_modes; i++) {  		const struct drm_display_mode *m = &panel->desc->modes[i]; -		mode = drm_mode_duplicate(drm, m); +		mode = drm_mode_duplicate(connector->dev, m);  		if (!mode) { -			dev_err(drm->dev, "failed to add mode %ux%u@%u\n", +			dev_err(panel->base.dev, "failed to add mode %ux%u@%u\n",  				m->hdisplay, m->vdisplay, m->vrefresh);  			continue;  		} @@ -183,10 +179,9 @@ static unsigned int panel_simple_get_display_modes(struct panel_simple *panel)  	return num;  } -static int panel_simple_get_non_edid_modes(struct panel_simple *panel) +static int panel_simple_get_non_edid_modes(struct panel_simple *panel, +					   struct drm_connector *connector)  { -	struct drm_connector *connector = panel->base.connector; -	struct drm_device *drm = panel->base.drm;  	struct drm_display_mode *mode;  	bool has_override = panel->override_mode.type;  	unsigned int num = 0; @@ -195,18 +190,19 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel)  		return 0;  	if (has_override) { -		mode = drm_mode_duplicate(drm, &panel->override_mode); +		mode = drm_mode_duplicate(connector->dev, +					  &panel->override_mode);  		if (mode) {  			drm_mode_probed_add(connector, mode);  			num = 1;  		} else { -			dev_err(drm->dev, "failed to add override mode\n"); +			dev_err(panel->base.dev, "failed to add override mode\n");  		}  	}  	/* Only add timings if override was not there or failed to validate */  	if (num == 0 && panel->desc->num_timings) -		num = panel_simple_get_timings_modes(panel); +		num = panel_simple_get_timings_modes(panel, connector);  	/*  	 * Only add fixed modes if timings/override added no mode. @@ -216,7 +212,7 @@ static int panel_simple_get_non_edid_modes(struct panel_simple *panel)  	 */  	WARN_ON(panel->desc->num_timings && panel->desc->num_modes);  	if (num == 0) -		num = panel_simple_get_display_modes(panel); +		num = panel_simple_get_display_modes(panel, connector);  	connector->display_info.bpc = panel->desc->bpc;  	connector->display_info.width_mm = panel->desc->size.width; @@ -236,12 +232,6 @@ static int panel_simple_disable(struct drm_panel *panel)  	if (!p->enabled)  		return 0; -	if (p->backlight) { -		p->backlight->props.power = FB_BLANK_POWERDOWN; -		p->backlight->props.state |= BL_CORE_FBBLANK; -		backlight_update_status(p->backlight); -	} -  	if (p->desc->delay.disable)  		msleep(p->desc->delay.disable); @@ -307,34 +297,30 @@ static int panel_simple_enable(struct drm_panel *panel)  	if (p->desc->delay.enable)  		msleep(p->desc->delay.enable); -	if (p->backlight) { -		p->backlight->props.state &= ~BL_CORE_FBBLANK; -		p->backlight->props.power = FB_BLANK_UNBLANK; -		backlight_update_status(p->backlight); -	} -  	p->enabled = true;  	return 0;  } -static int panel_simple_get_modes(struct drm_panel *panel) +static int panel_simple_get_modes(struct drm_panel *panel, +				  struct drm_connector *connector)  {  	struct panel_simple *p = to_panel_simple(panel);  	int num = 0;  	/* probe EDID if a DDC bus is available */  	if (p->ddc) { -		struct edid *edid = drm_get_edid(panel->connector, p->ddc); -		drm_connector_update_edid_property(panel->connector, edid); +		struct edid *edid = drm_get_edid(connector, p->ddc); + +		drm_connector_update_edid_property(connector, edid);  		if (edid) { -			num += drm_add_edid_modes(panel->connector, edid); +			num += drm_add_edid_modes(connector, edid);  			kfree(edid);  		}  	}  	/* add hard-coded panel modes */ -	num += panel_simple_get_non_edid_modes(p); +	num += panel_simple_get_non_edid_modes(p, connector);  	return num;  } @@ -414,9 +400,9 @@ static void panel_simple_parse_panel_timing_node(struct device *dev,  static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)  { -	struct device_node *backlight, *ddc;  	struct panel_simple *panel;  	struct display_timing dt; +	struct device_node *ddc;  	int err;  	panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); @@ -442,24 +428,13 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)  		return err;  	} -	backlight = of_parse_phandle(dev->of_node, "backlight", 0); -	if (backlight) { -		panel->backlight = of_find_backlight_by_node(backlight); -		of_node_put(backlight); - -		if (!panel->backlight) -			return -EPROBE_DEFER; -	} -  	ddc = of_parse_phandle(dev->of_node, "ddc-i2c-bus", 0);  	if (ddc) {  		panel->ddc = of_find_i2c_adapter_by_node(ddc);  		of_node_put(ddc); -		if (!panel->ddc) { -			err = -EPROBE_DEFER; -			goto free_backlight; -		} +		if (!panel->ddc) +			return -EPROBE_DEFER;  	}  	if (!of_get_display_timing(dev->of_node, "panel-timing", &dt)) @@ -468,6 +443,10 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)  	drm_panel_init(&panel->base, dev, &panel_simple_funcs,  		       desc->connector_type); +	err = drm_panel_of_backlight(&panel->base); +	if (err) +		goto free_ddc; +  	err = drm_panel_add(&panel->base);  	if (err < 0)  		goto free_ddc; @@ -479,9 +458,6 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)  free_ddc:  	if (panel->ddc)  		put_device(&panel->ddc->dev); -free_backlight: -	if (panel->backlight) -		put_device(&panel->backlight->dev);  	return err;  } @@ -491,16 +467,12 @@ static int panel_simple_remove(struct device *dev)  	struct panel_simple *panel = dev_get_drvdata(dev);  	drm_panel_remove(&panel->base); - -	panel_simple_disable(&panel->base); -	panel_simple_unprepare(&panel->base); +	drm_panel_disable(&panel->base); +	drm_panel_unprepare(&panel->base);  	if (panel->ddc)  		put_device(&panel->ddc->dev); -	if (panel->backlight) -		put_device(&panel->backlight->dev); -  	return 0;  } @@ -508,8 +480,8 @@ static void panel_simple_shutdown(struct device *dev)  {  	struct panel_simple *panel = dev_get_drvdata(dev); -	panel_simple_disable(&panel->base); -	panel_simple_unprepare(&panel->base); +	drm_panel_disable(&panel->base); +	drm_panel_unprepare(&panel->base);  }  static const struct drm_display_mode ampire_am_480272h3tmqw_t01h_mode = { @@ -657,6 +629,35 @@ static const struct panel_desc auo_b101xtn01 = {  	},  }; +static const struct drm_display_mode auo_b116xak01_mode = { +	.clock = 69300, +	.hdisplay = 1366, +	.hsync_start = 1366 + 48, +	.hsync_end = 1366 + 48 + 32, +	.htotal = 1366 + 48 + 32 + 10, +	.vdisplay = 768, +	.vsync_start = 768 + 4, +	.vsync_end = 768 + 4 + 6, +	.vtotal = 768 + 4 + 6 + 15, +	.vrefresh = 60, +	.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC, +}; + +static const struct panel_desc auo_b116xak01 = { +	.modes = &auo_b116xak01_mode, +	.num_modes = 1, +	.bpc = 6, +	.size = { +		.width = 256, +		.height = 144, +	}, +	.delay = { +		.hpd_absent_delay = 200, +	}, +	.bus_format = MEDIA_BUS_FMT_RGB666_1X18, +	.connector_type = DRM_MODE_CONNECTOR_eDP, +}; +  static const struct drm_display_mode auo_b116xw03_mode = {  	.clock = 70589,  	.hdisplay = 1366, @@ -1036,6 +1037,38 @@ static const struct panel_desc boe_nv101wxmn51 = {  	},  }; +static const struct drm_display_mode boe_nv140fhmn49_modes[] = { +	{ +		.clock = 148500, +		.hdisplay = 1920, +		.hsync_start = 1920 + 48, +		.hsync_end = 1920 + 48 + 32, +		.htotal = 2200, +		.vdisplay = 1080, +		.vsync_start = 1080 + 3, +		.vsync_end = 1080 + 3 + 5, +		.vtotal = 1125, +		.vrefresh = 60, +	}, +}; + +static const struct panel_desc boe_nv140fhmn49 = { +	.modes = boe_nv140fhmn49_modes, +	.num_modes = ARRAY_SIZE(boe_nv140fhmn49_modes), +	.bpc = 6, +	.size = { +		.width = 309, +		.height = 174, +	}, +	.delay = { +		.prepare = 210, +		.enable = 50, +		.unprepare = 160, +	}, +	.bus_format = MEDIA_BUS_FMT_RGB666_1X18, +	.connector_type = DRM_MODE_CONNECTOR_eDP, +}; +  static const struct drm_display_mode cdtech_s043wq26h_ct7_mode = {  	.clock = 9000,  	.hdisplay = 480, @@ -2061,6 +2094,40 @@ static const struct drm_display_mode mitsubishi_aa070mc01_mode = {  	.flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,  }; +static const struct drm_display_mode logicpd_type_28_mode = { +	.clock = 9000, +	.hdisplay = 480, +	.hsync_start = 480 + 3, +	.hsync_end = 480 + 3 + 42, +	.htotal = 480 + 3 + 42 + 2, + +	.vdisplay = 272, +	.vsync_start = 272 + 2, +	.vsync_end = 272 + 2 + 11, +	.vtotal = 272 + 2 + 11 + 3, +	.vrefresh = 60, +	.flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC, +}; + +static const struct panel_desc logicpd_type_28 = { +	.modes = &logicpd_type_28_mode, +	.num_modes = 1, +	.bpc = 8, +	.size = { +		.width = 105, +		.height = 67, +	}, +	.delay = { +		.prepare = 200, +		.enable = 200, +		.unprepare = 200, +		.disable = 200, +	}, +	.bus_format = MEDIA_BUS_FMT_RGB888_1X24, +	.bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE | +		     DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE, +}; +  static const struct panel_desc mitsubishi_aa070mc01 = {  	.modes = &mitsubishi_aa070mc01_mode,  	.num_modes = 1, @@ -2547,6 +2614,30 @@ static const struct panel_desc samsung_ltn140at29_301 = {  	},  }; +static const struct display_timing satoz_sat050at40h12r2_timing = { +	.pixelclock = {33300000, 33300000, 50000000}, +	.hactive = {800, 800, 800}, +	.hfront_porch = {16, 210, 354}, +	.hback_porch = {46, 46, 46}, +	.hsync_len = {1, 1, 40}, +	.vactive = {480, 480, 480}, +	.vfront_porch = {7, 22, 147}, +	.vback_porch = {23, 23, 23}, +	.vsync_len = {1, 1, 20}, +}; + +static const struct panel_desc satoz_sat050at40h12r2 = { +	.timings = &satoz_sat050at40h12r2_timing, +	.num_timings = 1, +	.bpc = 8, +	.size = { +		.width = 108, +		.height = 65, +	}, +	.bus_format = MEDIA_BUS_FMT_RGB888_1X24, +	.connector_type = DRM_MODE_CONNECTOR_LVDS, +}; +  static const struct drm_display_mode sharp_ld_d5116z01b_mode = {  	.clock = 168480,  	.hdisplay = 1920, @@ -3120,6 +3211,9 @@ static const struct of_device_id platform_of_match[] = {  		.compatible = "auo,b101xtn01",  		.data = &auo_b101xtn01,  	}, { +		.compatible = "auo,b116xa01", +		.data = &auo_b116xak01, +	}, {  		.compatible = "auo,b116xw03",  		.data = &auo_b116xw03,  	}, { @@ -3162,6 +3256,9 @@ static const struct of_device_id platform_of_match[] = {  		.compatible = "boe,nv101wxmn51",  		.data = &boe_nv101wxmn51,  	}, { +		.compatible = "boe,nv140fhmn49", +		.data = &boe_nv140fhmn49, +	}, {  		.compatible = "cdtech,s043wq26h-ct7",  		.data = &cdtech_s043wq26h_ct7,  	}, { @@ -3288,6 +3385,9 @@ static const struct of_device_id platform_of_match[] = {  		.compatible = "lg,lp129qe",  		.data = &lg_lp129qe,  	}, { +		.compatible = "logicpd,type28", +		.data = &logicpd_type_28, +	}, {  		.compatible = "mitsubishi,aa070mc01-ca1",  		.data = &mitsubishi_aa070mc01,  	}, { @@ -3348,6 +3448,9 @@ static const struct of_device_id platform_of_match[] = {  		.compatible = "samsung,ltn140at29-301",  		.data = &samsung_ltn140at29_301,  	}, { +		.compatible = "satoz,sat050at40h12r2", +		.data = &satoz_sat050at40h12r2, +	}, {  		.compatible = "sharp,ld-d5116z01b",  		.data = &sharp_ld_d5116z01b,  	}, { |